: Free pages from local pcp lists under tight memory conditions
Subsystems (5)
PATCH 1/1 : Free pages from local pcp lists under tight memory conditions
Andrew, Linus,
[PATCH]: This patch free pages (pcp->batch from each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from global free_list.
This should help fix some of the earlier failures seen with order 1 allocations.
I will send separate patches for:
1- Reducing the remote cpus pcp
2- Clean up page_alloc.c for CONFIG_HOTPLUG_CPU to use this code appropiately
mm/page_alloc.c +47 -2
@@ -827,6 +827,35 @@return page; } +static int +reduce_cpu_pcp (void ) +{ +struct zone *zone; +unsigned long flags; +unsigned int cpu =get_cpu (); +int i, ret=0 ; + +local_irq_save (flags); +for_each_zone (zone) { +struct per_cpu_pageset *pset; + + pset =zone_pcp (zone, cpu); +for (i =0 ; i <ARRAY_SIZE (pset->pcp); i++) { +struct per_cpu_pages *pcp; + + pcp = &pset->pcp[i]; +if (pcp->count ==0 ) +continue ; + pcp->count -=free_pages_bulk (zone, pcp->batch, + &pcp->list,0 ); + ret++; + } + } +local_irq_restore (flags); +put_cpu (); +return ret; +} +/* * This is the 'heart' of the zoned buddy allocator. */
@@ -887,6 +916,7 @@* Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc. * See also cpuset_zone_allowed() comment in kernel/cpuset.c. */ +try_again: page =get_page_from_freelist (gfp_mask, order, zonelist, alloc_flags);if (page) goto got_pg;
@@ -911,8 +941,15 @@ }/* Atomic allocations - we can't balance anything */ -if (!wait) - goto nopage; +if (!wait) { +/* Check if there are pages available on pcp lists that can be +* moved to global page list to satisfy higher order allocations. +*/ +if ((order >0 ) && (reduce_cpu_pcp ())) + goto try_again; +else + goto nopage; + } rebalance:cond_resched ();
@@ -950,6 +987,14 @@ goto restart; } +if (order >0 ) +while (reduce_cpu_pcp ()) { +if (get_page_from_freelist (gfp_mask, order, zonelist, alloc_flags)) + goto got_pg; + } +/* FIXME: Add the support for reducing/draining the remote pcps. +*/ +/* * Don't let big-order allocations loop unless the caller explicitly * requests that. Wait for some write requests to complete then retry.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 32 lines · Rohit Seth
Andrew, Linus,
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.This should help fix some of the earlier failures seen with order 1 allocations.
I will send separate patches for:
1- Reducing the remote cpus pcp
2- Clean uppage_alloc.cforCONFIG_HOTPLUG_CPUto use this code appropiately(quoted diff) +18
-0+static int +reduce_cpu_pcp(void ) +{ + struct zone *zone; + unsigned long flags; + unsigned int cpu = get_cpu(); + int i, ret=0; + + local_irq_save(flags); + for_each_zone(zone) { + struct per_cpu_pageset *pset; + + pset = zone_pcp(zone, cpu); + for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { + struct per_cpu_pages *pcp; + + pcp = &pset->pcp[i]; + if (pcp->count == 0)
Review
Quoted 10 lines
(quoted diff) +10
-0+ continue; + pcp->count -= free_pages_bulk(zone, pcp->batch, + &pcp->list, 0); + ret++; + } + } + local_irq_restore(flags); + put_cpu(); + return ret; +}
This significantly duplicates the existing drain_local_pages().
Review
Quoted 4 lines
(quoted diff) +3
-0+ if (order > 0) + while (reduce_cpu_pcp()) { + if (get_page_from_freelist(gfp_mask, order, zonelist, alloc_flags))
This forgot to assign to local variable `page'! It'll return NULL and will leak memory.
The `while' loop worries me for some reason, so I wimped out and just tried the remote drain once.
Review
Quoted 3 lines
(quoted diff) +3
-0+ goto got_pg; + } + /* FIXME: Add the support for reducing/draining the remote pcps.
This is easy enough to do.
I wanted to call the all-CPU drainer `drain_remote_pages' but that's already taken by some rather poorly-named NUMA thing which also duplicates most of __drain_pages().
This patch is against a random selection of the enormous number of mm/ patches in -mm. I haven't runtime-tested it yet.
We need to verify that this patch actually does something useful.
include/linux/gfp.h | 2 + include/linux/suspend.h | 1 mm/page_alloc.c | 85 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 66 insertions(+), 22 deletions(-)
include/linux/gfp.h renamed from include/linux/gfp.h~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +2 -0
@@ -109,6 +109,8 @@ static inline struct page *alloc_pages_n NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask)); } +extern int drain_local_pages (void ); +#ifdef CONFIG_NUMA extern struct page *alloc_pages_current (gfp_t gfp_mask,unsigned order);
include/linux/suspend.h renamed from include/linux/suspend.h~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +0 -1
@@ -40,7 +40,6 @@ extern dev_t swsusp_resume_device;extern int shrink_mem (void );/* mm/page_alloc.c */ -extern void drain_local_pages (void );extern void mark_free_pages (struct zone *zone);#ifdef CONFIG_PM
mm/page_alloc.c renamed from mm/page_alloc.c~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +64 -21
127 lines not on this page · raw message
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 3 lines · Andrew Morton
The `while' loop worries me for some reason, so I wimped out and just tried
the remote drain once.
Even the `goto restart' which is in this patch worries me from a livelock POV. Perhaps we should only ever run drain_all_local_pages() once per __alloc_pages() invokation.
And perhaps we should run drain_all_local_pages() for GFP_ATOMIC or PF_MEMALLOC attempts too.
include/linux/gfp.h renamed from include/linux/gfp.h~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +2 -0
@@ -109,6 +109,8 @@ static inline struct page *alloc_pages_n NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask)); } +extern void drain_local_pages (void ); +#ifdef CONFIG_NUMA extern struct page *alloc_pages_current (gfp_t gfp_mask,unsigned order);
include/linux/suspend.h renamed from include/linux/suspend.h~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +0 -1
@@ -40,7 +40,6 @@ extern dev_t swsusp_resume_device;extern int shrink_mem (void );/* mm/page_alloc.c */ -extern void drain_local_pages (void );extern void mark_free_pages (struct zone *zone);#ifdef CONFIG_PM
mm/page_alloc.c renamed from mm/page_alloc.c~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +45 -19
100 lines not on this page · raw message
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Andrew Morton
Quoted 3 lines · Andrew Morton
The `while' loop worries me for some reason, so I wimped out and just tried
the remote drain once.Even the `goto restart' which is in this patch worries me from a livelock POV. Perhaps we should only ever run
drain_all_local_pages()once per__alloc_pages()invokation.
And perhaps we should rundrain_all_local_pages()forGFP_ATOMICorPF_MEMALLOCattempts too.
Good point for PF_MEMALLOC scenario.
-rohit
Quoted 9 lines · Andrew Morton
Quoted 9 lines
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.This should help fix some of the earlier failures seen with order 1 allocations.
I will send separate patches for:
1- Reducing the remote cpus pcp
That is already partially done by drain_remote_pages(). However, that draining is specific to this processors remote pagesets in remote zones.
Quoted 1 line
This significantly duplicates the existing
drain_local_pages().
We need to extract __drain_pcp from all these functions and clearly document how they differ. Seth probably needs to call __drain_pages for each processor.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 1 line · Andrew Morton
+extern int
drain_local_pages(void);
drain_cpu_pcps?
The naming scheme is a bit confusing right now. We drain the pcp structures not pages so maybe switch to pcp and then name each function so that the function can be distinguishes clearlyu?
Quoted 1 line
+static int
drain_all_local_pages(void)
drain_all_pcps?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 5 lines · Christoph Lameter
Quoted 1 line · Andrew Morton
+extern int
drain_local_pages(void);
drain_cpu_pcps?
Please no.
If there is something I _hate_ it's bad naming. And "pcps" is a totally unintelligible name.
Write it out. If a function is so trivial that you can't be bothered to write out what the name means, that function shouldn't exist at all. Conversely, if it's worth doing, it's worth writing out a name.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 5 lines · Linus Torvalds
Quoted 3 lines · Christoph Lameter
Quoted 1 line · Andrew Morton
+extern int
drain_local_pages(void);
drain_cpu_pcps?
Quoted 8 lines
Please no.
If there is something I _hate_ it's bad naming. And "pcps" is a totally unintelligible name.
Write it out. If a function is so trivial that you can't be bothered to write out what the name means, that function shouldn't exist at all. Conversely, if it's worth doing, it's worth writing out a name.
drain_one_cpus_pages_from_per_cpu_pagesets()
drain_one_cpus_remote_pages_from_per_cpu_pagesets()
drain_all_per_cpu_pagesets()
?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 12 lines · Andrew Morton
Quoted 11 lines · Rohit Seth
Andrew, Linus,
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.This should help fix some of the earlier failures seen with order 1 allocations.
I will send separate patches for:
Quoted 7 lines
Review
Quoted 6 lines
1- Reducing the remote cpus pcp
2- Clean uppage_alloc.cforCONFIG_HOTPLUG_CPUto use this code appropiately(quoted diff) +2
-0+static int +reduce_cpu_pcp(void )This significantly duplicates the existing
drain_local_pages().
Yes. The main change in this new function is I'm only freeing batch number of pages from each pcp rather than draining out all of them (even under a little memory pressure). IMO, we should be more opportunistic here in alloc_pages in moving pages back to global page pool list. Thoughts?
As said earlier, I will be cleaning up the existing drain_local_pages in next follow up patch.
Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +3
-0+ if (order > 0) + while (reduce_cpu_pcp()) { + if (get_page_from_freelist(gfp_mask, order, zonelist, alloc_flags))This forgot to assign to local variable `page'! It'll return NULL and will leak memory.
My bad. Will fix it.
Quoted 3 lines
The `while' loop worries me for some reason, so I wimped out and just tried the remote drain once.
Even after direct reclaim it probably does make sense to see how minimally we can service a higher order request.
Quoted 6 lines
mm/page_alloc.c rebalance:
Quoted 3 lines
mm/page_alloc.c renamed from mm/page_alloc.c~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +3
-0+ goto got_pg; + } +/* FIXME: Add the support for reducing/draining the remote pcps. This is easy enough to do.
The couple of options that I wanted to think little more were (before attempting to do this part):
1- Whether use the IPI to get the remote CPUs to free pages from pcp or do it lazily (using work_pending or such). As at this point in execution we can definitely afford to get scheduled out.
2- Do we drain the whole pcp on remote processors or again follow the stepped approach (but may be with a steeper slope).
Quoted 3 lines
We need to verify that this patch actually does something useful.
I'm working on this. Will let you know later today if I can come with some workload easily hitting this additional logic.
Thanks,
-rohit
Quoted 21 lines · Rohit Seth
Quoted 12 lines · Andrew Morton
Quoted 11 lines · Rohit Seth
Andrew, Linus,
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.This should help fix some of the earlier failures seen with order 1 allocations.
I will send separate patches for:
Quoted 7 lines
Review
Quoted 6 lines
1- Reducing the remote cpus pcp
2- Clean uppage_alloc.cforCONFIG_HOTPLUG_CPUto use this code appropiately(quoted diff) +2
-0+static int +reduce_cpu_pcp(void )This significantly duplicates the existing
drain_local_pages().
Quoted 6 lines
Yes. The main change in this new function is I'm only freeing batch number of pages from each pcp rather than draining out all of them (even under a little memory pressure). IMO, we should be more opportunistic here in
alloc_pagesin moving pages back to global page pool list. Thoughts?
I doubt you gain a whole lot by releasing them in batches. There is no way to determine if freeing a few will result in contiguous blocks or not and the overhead of been cautious will likely exceed the cost of simply refilling them on the next order-0 allocation. Your worst case is where the buddies you need are in different per-cpu caches.
As it's easy to refill a per-cpu cache, it would be easier, clearer and probably faster to just purge the per-cpu cache and have it refilled on the next order-0 allocation. The release-in-batch approach would only be worthwhile if you expect an order-1 allocation to be very rare.
Quoted 12 lines
As said earlier, I will be cleaning up the existing
drain_local_pagesin next follow up patch.Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +3
-0+ if (order > 0) + while (reduce_cpu_pcp()) { + if (get_page_from_freelist(gfp_mask, order, zonelist, alloc_flags))This forgot to assign to local variable `page'! It'll return NULL and will leak memory.
Quoted 8 lines
My bad. Will fix it.
Quoted 3 lines
The `while' loop worries me for some reason, so I wimped out and just tried the remote drain once.
Even after direct reclaim it probably does make sense to see how minimally we can service a higher order request.
After direct reclaim, things are already very slow. The cost of refilling a per-cpu cache is nowhere near the same as a direct-reclaim.
Quoted 7 lines
Quoted 6 lines
mm/page_alloc.c rebalance:
Quoted 3 lines
mm/page_alloc.c renamed from mm/page_alloc.c~mm-free-pages-from-local-pcp-lists-under-tight-memory-conditions +3
-0+ goto got_pg; + } +/* FIXME: Add the support for reducing/draining the remote pcps. This is easy enough to do.
Quoted 7 lines
The couple of options that I wanted to think little more were (before attempting to do this part):
1- Whether use the IPI to get the remote CPUs to free pages from pcp or do it lazily (using
work_pendingor such). As at this point in execution we can definitely afford to get scheduled out.
In 005_drainpercpu.patch from the last version of the anti-defrag, I used the smp_call_function() and it did not seem to slow up the system. Certainly, by the time it was called, the system was already low on memory and trashing a bit so it just wasn't noticable.
Quoted 3 lines
2- Do we drain the whole pcp on remote processors or again follow the stepped approach (but may be with a steeper slope).
I would say do the same on the remote case as you do locally to keep things consistent.
Quoted 7 lines
Quoted 4 lines
We need to verify that this patch actually does something useful.
I'm working on this. Will let you know later today if I can come with some workload easily hitting this additional logic.
I found it hard to generate reliable workloads which hit these sort of situations although a fork-heavy workload with 8k stacks will put pressure on order-1 allocations. You can artifically force high order allocations using vmregress by doing something like this;
./configure --with-linux=/usr/src/linux-yourtree
make
insmod kernel_src/core/vmregress_core.ko
insmod kernel_src/core/buddyinfo.ko
insmod kernel_src/test/highalloc.ko
echo 1 100 > /proc/vmregress/test_highalloc
That will allocate 1 order-1 page every tenth of a second until it has tried 100 allocations. When it completes, the success/failure report can be read by catting /proc/vmregress/test_highalloc. Obviously, this is very artifical.
Signature · 9 lines
Mel Gorman Part-time Phd Student Java Applications Developer University of Limerick IBM Dublin Software Lab -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 7 lines · Mel Gorman
Quoted 1 line · Rohit Seth
I doubt you gain a whole lot by releasing them in batches. There is no way to determine if freeing a few will result in contiguous blocks or not and the overhead of been cautious will likely exceed the cost of simply refilling them on the next order-0 allocation.
It depends. If most of the higher order allocations are only order 1 (and may be order 2) then it is possible that we may gain in freeing in batches.
Quoted 3 lines
Your worst case is where
the buddies you need are in different per-cpu caches.
That is why we need another patch that tries to allocate physically contiguous pages in each per_cpu_pagelist. Actually this patch used to be there in Andrew's tree for some time (2.6.14) before couple of corner cases came up failing where order 1 allocations were unsuccessful.
Quoted 5 lines
As it's easy to refill a per-cpu cache, it would be easier, clearer and probably faster to just purge the per-cpu cache and have it refilled on the next order-0 allocation. The release-in-batch approach would only be worthwhile if you expect an order-1 allocation to be very rare.
Well, my only fear is if this shunting happens too often...
Quoted 5 lines
In 005_drainpercpu.patch from the last version of the anti-defrag, I used the
smp_call_function()and it did not seem to slow up the system. Certainly, by the time it was called, the system was already low on memory and trashing a bit so it just wasn't noticable.
I agree at this point in alloaction, speed probably does not matter too much. I definitely want to first see for simple workloads how much (and how deep we have to go into deallocations) this extra logic helps.
Quoted 7 lines
Quoted 3 lines
2- Do we drain the whole pcp on remote processors or again follow the stepped approach (but may be with a steeper slope).
I would say do the same on the remote case as you do locally to keep things consistent.
Well, I think in bigger scope these allocations/deallocations will get automatically balanced.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
We need to verify that this patch actually does something useful.
Quoted 8 lines
Quoted 3 lines
I'm working on this. Will let you know later today if I can come with some workload easily hitting this additional logic.
I found it hard to generate reliable workloads which hit these sort of situations although a fork-heavy workload with 8k stacks will put pressure on order-1 allocations. You can artifically force high order allocations using vmregress by doing something like this;
Need something more benign/stupid to kick into this logic.
-rohit
Quoted 4 lines · Rohit Seth
Quoted 3 lines · Mel Gorman
Quoted 1 line · Rohit Seth
Quoted 9 lines
Quoted 4 lines
I doubt you gain a whole lot by releasing them in batches. There is no way to determine if freeing a few will result in contiguous blocks or not and the overhead of been cautious will likely exceed the cost of simply refilling them on the next order-0 allocation.
It depends. If most of the higher order allocations are only order 1 (and may be order 2) then it is possible that we may gain in freeing in batches.
Possible, but if you are draining, it's just as handy to drain them all and avoid >0 order failures in the near future.
Quoted 6 lines
Quoted 3 lines
Your worst case is where
the buddies you need are in different per-cpu caches.That is why we need another patch that tries to allocate physically contiguous pages in each
per_cpu_pagelist.
That will only delay the problem. Pages end up on the per-cpu lists from either an allocation or a free. While the allocation would make sure the pages were contiguous and on the same list, the frees will not. The test case you are running is a tight loop of one process allocating and freeing order-1 pages. This is probably staying on the one CPU so draining in batches on just the local CPU will appear successful. On long lived loads, it will not be as successful. Draining all the pages on all lists would cover all cases while using the existing code.
When I was testing my version of drain-percpu for anti-defrag and order-10 allocations, I found that draining just the local CPU made little difference but draining all of them made a massive difference. This is an extreme case, but it still applies to the smaller orders.
Quoted 4 lines
Actually this patch used to
be there in Andrew's tree for some time (2.6.14) before couple of corner cases came up failing where order 1 allocations were unsuccessful.
Quoted 8 lines
Quoted 5 lines
As it's easy to refill a per-cpu cache, it would be easier, clearer and probably faster to just purge the per-cpu cache and have it refilled on the next order-0 allocation. The release-in-batch approach would only be worthwhile if you expect an order-1 allocation to be very rare.
Well, my only fear is if this shunting happens too often...
Measure it by counting how often you drain the pages and add it to frag_show(). This is a hack obviously and not a permanent solution, but it's the easiest way to find out what's going on.
Quoted 14 lines
Quoted 5 lines
In 005_drainpercpu.patch from the last version of the anti-defrag, I used the
smp_call_function()and it did not seem to slow up the system. Certainly, by the time it was called, the system was already low on memory and trashing a bit so it just wasn't noticable.I agree at this point in alloaction, speed probably does not matter too much. I definitely want to first see for simple workloads how much (and how deep we have to go into deallocations) this extra logic helps.
Quoted 4 lines
Quoted 3 lines
2- Do we drain the whole pcp on remote processors or again follow the stepped approach (but may be with a steeper slope).
Quoted 7 lines
Quoted 3 lines
I would say do the same on the remote case as you do locally to keep things consistent.
Well, I think in bigger scope these allocations/deallocations will get automatically balanced.
Depends on if your workload involves one or more processes. If the load is multiple processes on multiple CPUs, the per-cpu pages will be spread out a lot.
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 4 lines
We need to verify that this patch actually does something useful.
I'm working on this. Will let you know later today if I can come with some workload easily hitting this additional logic.
Quoted 7 lines
Quoted 4 lines
I found it hard to generate reliable workloads which hit these sort of situations although a fork-heavy workload with 8k stacks will put pressure on order-1 allocations. You can artifically force high order allocations using vmregress by doing something like this;
Need something more benign/stupid to kick into this logic.
If CIFS still needs high order allocations, you could try -jN kernel compiles over the network filesystem. Network benchmarks running over a loopback device with a large MTU while another load consumes memory might also trigger it.
Signature · 9 lines
Mel Gorman Part-time Phd Student Java Applications Developer University of Limerick IBM Dublin Software Lab -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Rohit Seth
Quoted 9 lines · Andrew Morton
Quoted 4 lines
We need to verify that this patch actually does something useful.
I'm working on this. Will let you know later today if I can come with some workload easily hitting this additional logic.
I'm able to trigger the reduce_cpu_pcp (I'll change its name in next update patch) logic after direct reclaim using a small test case hogging memory and a bash loop spawning another process 1 at a time using very little memory.
I added a single printk after the direct reclaim where we reduce the per cpu pagelist (in my patch) just to get the order and how many iterations do we need to service the request. order is always 1 (coming from alloc_thread_info for 8K stack size).
This is on i386 with 8K stack size.
if (order > 0) {
int i = 0;
while (reduce_cpu_pcp()) {
i++;
page = get_page_from_freelist(gfp_mask, order, zonelist,
alloc_flags);
if (page) {
printk("Got page %d order iteration %d", order, i);
goto got_pg;
}
}
}And got about 30 of those in couple of hours:
[17179885.360000] Got page 1 order iteration 1
Quoted 3 lines · Rohit Seth
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.
Ummm.. One controversial idea: How about removing the complete pcp subsystem? Last time we disabled pcps we saw that the effect that it had was within noise ratio on AIM7. The lru lock taken without pcp is in the local zone and thus rarely contended.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Christoph Lameter
Quoted 3 lines · Rohit Seth
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.Ummm.. One controversial idea: How about removing the complete pcp subsystem? Last time we disabled pcps we saw that the effect that it had was within noise ratio on AIM7. The lru lock taken without pcp is in the local zone and thus rarely contended.
Oh please stop.
This per_cpu_pagelist is one great logic that has got added in allocator. Besides providing pages without the need to acquire the zone lock, it is one single main reason the coloring effect is drastically reduced in 2.6 (over 2.4) based kernels.
-rohit
Quoted 13 lines · Rohit Seth
Quoted 10 lines · Christoph Lameter
Quoted 3 lines · Rohit Seth
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.Ummm.. One controversial idea: How about removing the complete pcp subsystem? Last time we disabled pcps we saw that the effect that it had was within noise ratio on AIM7. The lru lock taken without pcp is in the local zone and thus rarely contended.
Quoted 7 lines
Oh please stop.
This
per_cpu_pagelistis one great logic that has got added in allocator. Besides providing pages without the need to acquire the zone lock, it is one single main reason the coloring effect is drastically reduced in 2.6 (over 2.4) based kernels.
hm. Before it was merged in 2.5.x, the feature was very marginal from a performance POV in my testing on 4-way.
I was able to demonstrate a large (~60%?) speedup in one microbenckmark which consisted of four processes writing 16k to a file and truncating it back to zero again. That gain came from the cache warmth effect, which is the other benefit which these cpu-local pages are supposed to provide.
I don't think Martin was able to demonstrate much benefit from the lock contention reduction on 16-way NUMAQ either.
So I dithered for months and it was a marginal merge, so it's appropriate to justify the continued presence of the code.
We didn't measure for any coloring effects though. In fact, I didn't know that this feature actually provided any benefit in that area.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 16 lines · Andrew Morton
Quoted 15 lines · Rohit Seth
Quoted 10 lines · Christoph Lameter
Quoted 3 lines · Rohit Seth
[PATCH]: This patch free pages (
pcp->batchfrom each list at a time) from local pcp lists when a higher order allocation request is not able to get serviced from globalfree_list.Ummm.. One controversial idea: How about removing the complete pcp subsystem? Last time we disabled pcps we saw that the effect that it had was within noise ratio on AIM7. The lru lock taken without pcp is in the local zone and thus rarely contended.
Oh please stop.
Quoted 9 lines
Quoted 5 lines
This
per_cpu_pagelistis one great logic that has got added in allocator. Besides providing pages without the need to acquire the zone lock, it is one single main reason the coloring effect is drastically reduced in 2.6 (over 2.4) based kernels.hm. Before it was merged in 2.5.x, the feature was very marginal from a performance POV in my testing on 4-way.
One less lock to worry about in the page allocation should help somewhere I would assume.
Quoted 5 lines
I was able to demonstrate a large (~60%?) speedup in one microbenckmark which consisted of four processes writing 16k to a file and truncating it back to zero again. That gain came from the cache warmth effect, which is the other benefit which these cpu-local pages are supposed to provide.
That is right.
Quoted 6 lines
I don't think Martin was able to demonstrate much benefit from the lock contention reduction on 16-way NUMAQ either.
So I dithered for months and it was a marginal merge, so it's appropriate to justify the continued presence of the code.
May be the limits on the number of pages hanging on the per_cpu_pagelist was (or even now is) too small (for them to give any meaningful gain). May be we should have more physical contiguity in each of these pcps to give better cache spread.
Quoted 2 lines
We didn't measure for any coloring effects though. In fact, I didn't know that this feature actually provided any benefit in that area.
I thought Nick et.al came up with some of the constant values like batch size to tackle the page coloring issue specifically. In any case, I think one of the key difference between 2.4 and 2.6 allocators is the pcp list. And even with the minuscule batch and high watermarks this is helping ordinary benchmarks (by reducing the variation from run to run).
-rohit
Quoted 5 lines · Rohit Seth
I thought Nick et.al came up with some of the constant values like batch size to tackle the page coloring issue specifically. In any case, I think one of the key difference between 2.4 and 2.6 allocators is the pcp list. And even with the minuscule batch and high watermarks this is helping ordinary benchmarks (by reducing the variation from run to run).
Could you share some benchmark results?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Christoph Lameter
Quoted 5 lines · Rohit Seth
I thought Nick et.al came up with some of the constant values like batch size to tackle the page coloring issue specifically. In any case, I think one of the key difference between 2.4 and 2.6 allocators is the pcp list. And even with the minuscule batch and high watermarks this is helping ordinary benchmarks (by reducing the variation from run to run).
Could you share some benchmark results?
Some components of cpu2k on 2.4 base kernels show in access of 40-50% variation from run to run. The same variations came down to about 10% for 2.6 based kernels.
-rohit
Quoted 4 lines · Rohit Seth
Quoted 4 lines
I don't think Martin was able to demonstrate much benefit from the lock contention reduction on 16-way NUMAQ either.
Quoted 8 lines
Quoted 3 lines
So I dithered for months and it was a marginal merge, so it's appropriate to justify the continued presence of the code.
May be the limits on the number of pages hanging on the
per_cpu_pagelistwas (or even now is) too small (for them to give any meaningful gain). May be we should have more physical contiguity in each of these pcps to give better cache spread.
Could be. The initial settings were pretty arbitrary - I assumed that someone would get in and tune them up, but nothing much happened. Perhaps we should expose the thresholds in /proc/sys/vm so they're easier to play with.
Quoted 8 lines
Quoted 2 lines
We didn't measure for any coloring effects though. In fact, I didn't know that this feature actually provided any benefit in that area.
I thought Nick et.al came up with some of the constant values like batch size to tackle the page coloring issue specifically. In any case, I think one of the key difference between 2.4 and 2.6 allocators is the pcp list. And even with the minuscule batch and high watermarks this is helping ordinary benchmarks (by reducing the variation from run to run).
OK, useful info, thanks.
Quoted 14 lines · Andrew Morton
Quoted 4 lines · Rohit Seth
Quoted 4 lines
I don't think Martin was able to demonstrate much benefit from the lock contention reduction on 16-way NUMAQ either.
Quoted 8 lines
Quoted 3 lines
So I dithered for months and it was a marginal merge, so it's appropriate to justify the continued presence of the code.
May be the limits on the number of pages hanging on the
per_cpu_pagelistwas (or even now is) too small (for them to give any meaningful gain). May be we should have more physical contiguity in each of these pcps to give better cache spread.
Quoted 4 lines
Could be. The initial settings were pretty arbitrary - I assumed that someone would get in and tune them up, but nothing much happened. Perhaps we should expose the thresholds in
/proc/sys/vmso they're easier to play with.
Most certainly. If I had a patch ready...I would have given you one right away :-) Though I will work on it...
It surely is unfortunate that we have not digged deeper into this area (in terms of optimizations)....
-rohit
Quoted 2 lines · Rohit
I thought Nick et.al came up with some of the constant values like batch size to tackle the page coloring issue specifically.
I think this came about on a linux-ia64 thread started by Jack Steiner:
http://www.gelato.unsw.edu.au/archives/linux-ia64/0504/13668.html
Subject: per_cpu_pagesets degrades MPI performance
From: Jack Steiner <steiner_at_sgi.com>
Date: 2005-04-05 05:28:27
Jack reported that per_cpu_pagesets were degrading some MPI benchmarks due to adverse page coloring. Nick responded, recommending a non-power of two batch size. Jack found that this helped nicely. This thread trails off, but seems to be the origins of the 2**n-1 batch size in:
mm/page_alloc.c:zone_batchsize()
* Clamp the batch to a 2^n - 1 value. Having a power ...
batch = (1 << fls(batch + batch/2)) - 1;I don't see here evidence that "per_cpu_pagelist is ... one single main reason the coloring effect is drastically reduced in 2.6 (over 2.4) based kernels." Rather in this case anyway a batch size not a power of two was apparently needed to keep per_cpu_pagesets from hurting performance due to page coloring affects on some workloads.
Signature · 9 lines
I won't rest till it's the best ...
Programmer, Linux Scalability
Paul Jackson <[email protected]> 1.925.600.0401
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>Quoted 20 lines · Paul Jackson
Quoted 2 lines · Rohit
I thought Nick et.al came up with some of the constant values like batch size to tackle the page coloring issue specifically.
I think this came about on a linux-ia64 thread started by Jack Steiner:
http://www.gelato.unsw.edu.au/archives/linux-ia64/0504/13668.html
Subject:per_cpu_pagesetsdegrades MPI performance
From: Jack Steiner <steiner_at_sgi.com>
Date: 2005-04-05 05:28:27Jack reported that
per_cpu_pagesetswere degrading some MPI benchmarks due to adverse page coloring. Nick responded, recommending a non-power of two batch size. Jack found that this helped nicely. This thread trails off, but seems to be the origins of the 2**n-1 batch size in:mm/page_alloc.c:zone_batchsize() * Clamp the batch to a 2^n - 1 value. Having a power ... batch = (1 << fls(batch + batch/2)) - 1;
Quoted 6 lines
I don't see here evidence that "
per_cpu_pagelistis ... one single main reason the coloring effect is drastically reduced in 2.6 (over 2.4) based kernels." Rather in this case anyway a batch size not a power of two was apparently needed to keepper_cpu_pagesetsfrom hurting performance due to page coloring affects on some workloads.
Well, the batch size of a list ( + the high mark) are integral part of per_cpu_pagelist infrastructure. Tuning is always required. I don't think though one fixed set of values is fixing all the cases.
Can you please comment on the performance delta on the MPI workload because of this change in batch values. And what were the numbers before per_cpu_pagelists were introduced.
thanks,
-rohit
Quoted 2 lines · Rohit
Can you please comment on the performance delta on the MPI workload because of this change in batch values.
I can't -- all I know is what I read in Jack Steiner's posts of April 5, 2005, referenced earlier in this thread.
Signature · 9 lines
I won't rest till it's the best ...
Programmer, Linux Scalability
Paul Jackson <[email protected]> 1.925.600.0401
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>Quoted 9 lines · Paul Jackson
Quoted 2 lines · Rohit
Can you please comment on the performance delta on the MPI workload because of this change in batch values.
I can't -- all I know is what I read in Jack Steiner's posts of April 5, 2005, referenced earlier in this thread.
It was something fairly large. Basically having a power of 2 batch size meant that 2 concurrent allocators (presumably setting up the working area) would alternately pull in power of 2 chunks of memory, which caused each CPU to only get pages of ~half of its cache's possible colours.
The fix is not by any means a single value for all workloads, it simply avoids powers of 2 batch size. Note this will have very little effect on single threaded allocators and will do nothing for cache colouring there, however it is important for concurrent allocators.
Nick
Signature · 9 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 4 lines · Andrew Morton
I was able to demonstrate a large (~60%?) speedup in one microbenckmark which consisted of four processes writing 16k to a file and truncating it back to zero again. That gain came from the cache warmth effect, which is the other benefit which these cpu-local pages are supposed to provide.
Maybe we can cut the pcp logic back to only put cache warm pages into a single per_cpu pcp list for the local processor that contains node local pages? Return all remote pages and cold pages directly to the buddy lists.
That way we can remove the logic to flush remote pages and remove those pcp lists for remote nodes that are mostly empty anyways.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>