vmscan: bail out of page reclaim after swap_cluster_max pages
Subsystems (3)
PATCH 1/1 vmscan: bail out of page reclaim after swap_cluster_max pages
Sometimes the VM spends the first few priority rounds rotating back referenced pages and submitting IO. Once we get to a lower priority, sometimes the VM ends up freeing way too many pages.
The fix is relatively simple: in shrink_zone() we can check how many pages we have already freed, direct reclaim tasks break out of the scanning loop if they have already freed enough pages and have reached a lower priority level.
However, in order to do this we do need to know how many pages we already freed, so move nr_reclaimed into scan_control.
---
Kosaki, this should address the zone scanning pressure issue.
Nick, this includes the cleanups suggested by you.
mm/vmscan.c | 62 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 29 deletions(-)
mm/vmscan.c +33 -29
@@ -52,6 +52,9 @@ struct scan_control {/* Incremented by the number of inactive pages that were scanned */ unsigned long nr_scanned; +/* Number of pages freed so far during a call to shrink_zones() */ +unsigned long nr_reclaimed; +/* This context's GFP mask */ gfp_t gfp_mask;
@@ -1405,12 +1408,11 @@ static void get_scan_ratio(struct zone */* * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. */ -static unsigned long shrink_zone (int priority,struct zone *zone, +static void shrink_zone (int priority,struct zone *zone,struct scan_control *sc) {unsigned long nr[NR_LRU_LISTS ];unsigned long nr_to_scan; -unsigned long nr_reclaimed =0 ;unsigned long percent[2 ];/* anon @ 0; file @ 1 */ enum lru_list l;
@@ -1451,10 +1453,21 @@ static unsigned long shrink_zone(int pri (unsigned long)sc->swap_cluster_max); nr[l] -= nr_to_scan; - nr_reclaimed +=shrink_list (l, nr_to_scan, + sc->nr_reclaimed +=shrink_list (l, nr_to_scan, zone, sc, priority); } } +/* +* On large memory systems, scan >> priority can become +* really large. This is fine for the starting priority; +* we want to put equal scanning pressure on each zone. +* However, if the VM has a harder time of freeing pages, +* with multiple processes reclaiming pages, the total +* freeing target can get unreasonably large. +*/ +if (sc->nr_reclaimed > sc->swap_cluster_max && + sc->priority <DEF_PRIORITY && !current_is_kswapd ()) +break ; }/*
@@ -1467,7 +1480,6 @@ static unsigned long shrink_zone(int prishrink_active_list (SWAP_CLUSTER_MAX , zone, sc, priority,0 );throttle_vm_writeout (sc->gfp_mask); -return nr_reclaimed; }/*
@@ -1481,16 +1493,13 @@ static unsigned long shrink_zone(int pri* b) The zones may be over pages_high but they must go *over* pages_high to * satisfy the `incremental min' zone defense algorithm. * -* Returns the number of reclaimed pages. -* * If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static unsigned long shrink_zones (int priority,struct zonelist *zonelist, +static void shrink_zones (int priority,struct zonelist *zonelist,struct scan_control *sc) {enum zone_type high_zoneidx =gfp_zone (sc->gfp_mask); -unsigned long nr_reclaimed =0 ;struct zoneref *z;struct zone *zone;
@@ -1521,10 +1530,8 @@ static unsigned long shrink_zones(int pr priority); } - nr_reclaimed +=shrink_zone (priority, zone, sc); +shrink_zone (priority, zone, sc); } - -return nr_reclaimed; }/*
@@ -1549,7 +1556,6 @@ static unsigned long do_try_to_free_pageint priority;unsigned long ret =0 ;unsigned long total_scanned =0 ; -unsigned long nr_reclaimed =0 ;struct reclaim_state *reclaim_state = current->reclaim_state;unsigned long lru_pages =0 ;struct zoneref *z;
@@ -1577,7 +1583,7 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); - nr_reclaimed +=shrink_zones (priority, zonelist, sc); +shrink_zones (priority, zonelist, sc);/* * Don't shrink slabs when reclaiming memory from * over limit cgroups
@@ -1585,13 +1591,13 @@ static unsigned long do_try_to_free_pageif (scan_global_lru (sc)) {shrink_slab (sc->nr_scanned, sc->gfp_mask, lru_pages);if (reclaim_state) { - nr_reclaimed += reclaim_state->reclaimed_slab; + sc->nr_reclaimed += reclaim_state->reclaimed_slab; reclaim_state->reclaimed_slab =0 ; } } total_scanned += sc->nr_scanned; -if (nr_reclaimed >= sc->swap_cluster_max) { - ret = nr_reclaimed; +if (sc->nr_reclaimed >= sc->swap_cluster_max) { + ret = sc->nr_reclaimed; goto out; }
@@ -1614,7 +1620,7 @@ static unsigned long do_try_to_free_page }/* top priority shrink_zones still had more to do? don't OOM, then */ if (!sc->all_unreclaimable &&scan_global_lru (sc)) - ret = nr_reclaimed; + ret = sc->nr_reclaimed; out:/* * Now that we've scanned all the zones at this priority level, note
@@ -1709,7 +1715,6 @@ static unsigned long balance_pgdat(pg_daint priority;int i;unsigned long total_scanned; -unsigned long nr_reclaimed;struct reclaim_state *reclaim_state = current->reclaim_state;struct scan_control sc = { .gfp_mask =GFP_KERNEL ,
@@ -1728,7 +1733,7 @@ static unsigned long balance_pgdat(pg_da loop_again: total_scanned =0 ; - nr_reclaimed =0 ; + sc.nr_reclaimed =0 ; sc.may_writepage = !laptop_mode;count_vm_event (PAGEOUTRUN );
@@ -1814,11 +1819,11 @@ loop_again:*/ if (!zone_watermark_ok (zone, order,8 *zone->pages_high, end_zone,0 )) - nr_reclaimed +=shrink_zone (priority, zone, &sc); +shrink_zone (priority, zone, &sc); reclaim_state->reclaimed_slab =0 ; nr_slab =shrink_slab (sc.nr_scanned,GFP_KERNEL , lru_pages); - nr_reclaimed += reclaim_state->reclaimed_slab; + sc.nr_reclaimed += reclaim_state->reclaimed_slab; total_scanned += sc.nr_scanned;if (zone_is_all_unreclaimable (zone))continue ;
@@ -1832,7 +1837,7 @@ loop_again:* even in laptop mode */ if (total_scanned >SWAP_CLUSTER_MAX *2 && - total_scanned > nr_reclaimed + nr_reclaimed /2 ) + total_scanned > sc.nr_reclaimed + sc.nr_reclaimed /2 ) sc.may_writepage =1 ; }if (all_zones_ok)
@@ -1850,7 +1855,7 @@ loop_again:* matches the direct reclaim path behaviour in terms of impact * on zone->*_priority. */ -if (nr_reclaimed >=SWAP_CLUSTER_MAX ) +if (sc.nr_reclaimed >=SWAP_CLUSTER_MAX )break ; } out:
@@ -1872,7 +1877,7 @@ out: goto loop_again; } -return nr_reclaimed; +return sc.nr_reclaimed; }/*
@@ -2224,7 +2229,6 @@ static int __zone_reclaim(struct zone *zstruct task_struct *p = current;struct reclaim_state reclaim_state;int priority; -unsigned long nr_reclaimed =0 ;struct scan_control sc = { .may_writepage = !!(zone_reclaim_mode &RECLAIM_WRITE ), .may_swap = !!(zone_reclaim_mode &RECLAIM_SWAP ),
@@ -2257,9 +2261,9 @@ static int __zone_reclaim(struct zone *z priority =ZONE_RECLAIM_PRIORITY ;do {note_zone_scanning_priority (zone, priority); - nr_reclaimed +=shrink_zone (priority, zone, &sc); +shrink_zone (priority, zone, &sc); priority--; - }while (priority >=0 && nr_reclaimed < nr_pages); + }while (priority >=0 && sc.nr_reclaimed < nr_pages); } slab_reclaimable =zone_page_state (zone,NR_SLAB_RECLAIMABLE );
@@ -2283,13 +2287,13 @@ static int __zone_reclaim(struct zone *z* Update nr_reclaimed by the number of slab pages we * reclaimed from this zone. */ - nr_reclaimed += slab_reclaimable - + sc.nr_reclaimed += slab_reclaimable -zone_page_state (zone,NR_SLAB_RECLAIMABLE ); } p->reclaim_state =NULL ; current->flags &= ~(PF_MEMALLOC |PF_SWAPWRITE ); -return nr_reclaimed >= nr_pages; +return sc.nr_reclaimed >= nr_pages; }int zone_reclaim (struct zone *zone,gfp_t gfp_mask,unsigned int order)
--
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>
Andrew Morton
maintainerQuoted 3 lines · On Mon, 24 Nov 2008 14:50:57 -0500 Rik van Riel <[email protected]> wrote:
Sometimes the VM spends the first few priority rounds rotating back referenced pages and submitting IO. Once we get to a lower priority, sometimes the VM ends up freeing way too many pages.
It would help (a lot) if we had a much more specific and detailed description of the problem which is being fixed. Nobody has noticed it in half a decade, so it can't be very serious?
Quoted 4 lines
The fix is relatively simple: in
shrink_zone()we can check how many pages we have already freed, direct reclaim tasks break out of the scanning loop if they have already freed enough pages and have reached a lower priority level.
So in the common scenario where there's a lot of dirty highmem and little dirty lowmem, the kernel will start reclaiming highmem at a vastly higher rate than lowmem. iirc, this was the reason why this change was tried then reverted.
Please demonstrate that this regression is not worse than the problem which is being fixed!
Quoted 2 lines
However, in order to do this we do need to know how many pages we already freed, so move
nr_reclaimedintoscan_control.
Thus carrying the state across the *entire* scanning pass: all zones.
So as soon as sc.nr_reclaimed exceeds swap_cluster_max, the scanner will fall into a different mode for the remaining zones wherein it will scan only swap_cluster_max pages from them, then will bale.
This will heavily bias scanning onto the zones at the start of the zone list. In fact it probably means that the zone at the head of the zonelist gets thrashed and the remaining zones will just sit there doing almost nothing. Where's the sense in that?
Has any testing been done to demonstrate and quantify this effect?
Quoted 3 lines
Signed-off-by Rik van Riel <[email protected]>---
Kosaki, this should address the zone scanning pressure issue.
What is the "zone scanning pressure issue"?
Please don't put "should" in a vmscan changelog :( Either it does, or it does not?
This should look familiar:
commit e468e46a9bea3297011d5918663ce6d19094cf87
Author: akpm <akpm>
Date: Thu Jun 24 15:53:52 2004 +0000
[PATCH] vmscan.c: dont reclaim too many pages
The shrink_zone() logic can, under some circumstances, cause far too many pages to be reclaimed. Say, we're scanning at high priority and suddenly hit a large number of reclaimable pages on the LRU.
Change things so we bale out when SWAP_CLUSTER_MAX pages have been reclaimed.
BKrev: 40daf910sac4yN_aUhhJF2U8Upx1ww
And here is where it was reverted. Note that this was nearly two years later! It takes that long for these things to be discovered, analysed and fixed.
commit 210fe530305ee50cd889fe9250168228b2994f32
Author: Andrew Morton <[email protected]>
Date: Fri Jan 6 00:11:14 2006 -0800
[PATCH] vmscan: balancing fix
Revert a patch which went into 2.6.8-rc1. The changelog for that patch was:
The shrink_zone() logic can, under some circumstances, cause far too many pages to be reclaimed. Say, we're scanning at high priority and suddenly hit a large number of reclaimable pages on the LRU.
Change things so we bale out when SWAP_CLUSTER_MAX pages have been reclaimed.
Problem is, this change caused significant imbalance in inter-zone scan balancing by truncating scans of larger zones.
Suppose, for example, ZONE_HIGHMEM is 10x the size of ZONE_NORMAL. The zone balancing algorithm would require that if we're scanning 100 pages of ZONE_HIGHMEM, we should scan 10 pages of ZONE_NORMAL. But this logic will cause the scanning of ZONE_HIGHMEM to bale out after only 32 pages are reclaimed. Thus effectively causing smaller zones to be scanned relatively harder than large ones.
Now I need to remember what the workload was which caused me to write this patch originally, then fix it up in a different way...
--
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
Sometimes the VM spends the first few priority rounds rotating back referenced pages and submitting IO. Once we get to a lower priority, sometimes the VM ends up freeing way too many pages.
The fix is relatively simple: in
shrink_zone()we can check how many pages we have already freed, direct reclaim tasks break out of the scanning loop if they have already freed enough pages and have reached a lower priority level.
Quoted 6 lines
However, in order to do this we do need to know how many pages we already freed, so move
nr_reclaimedintoscan_control.Signed-off-by Rik van Riel <[email protected]>---
Kosaki, this should address the zone scanning pressure issue.
hmmmm. I still don't like the behavior when priority==DEF_PRIORITY. but I also should explain by code and benchmark.
therefore, I'll try to mesure this patch in this week.
thanks.
--
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 · KOSAKI Motohiro
Quoted 12 lines
Sometimes the VM spends the first few priority rounds rotating back referenced pages and submitting IO. Once we get to a lower priority, sometimes the VM ends up freeing way too many pages.
The fix is relatively simple: in
shrink_zone()we can check how many pages we have already freed, direct reclaim tasks break out of the scanning loop if they have already freed enough pages and have reached a lower priority level.However, in order to do this we do need to know how many pages we already freed, so move
nr_reclaimedintoscan_control.
Quoted 6 lines
Quoted 3 lines
Signed-off-by Rik van Riel <[email protected]>---
Kosaki, this should address the zone scanning pressure issue.hmmmm. I still don't like the behavior when priority==DEF_PRIORITY. but I also should explain by code and benchmark.
Well, the behaviour when priority==DEF_PRIORITY is the same as the kernel's behaviour without the patch...
Quoted 1 line
therefore, I'll try to mesure this patch in this week.
Looking forward to it.
Signature · 7 lines
All rights reversed. -- 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>
2008/11/25 Rik van Riel <[email protected]>:
Quoted 18 lines
Quoted 17 lines · KOSAKI Motohiro
Quoted 16 lines
Sometimes the VM spends the first few priority rounds rotating back referenced pages and submitting IO. Once we get to a lower priority, sometimes the VM ends up freeing way too many pages.
The fix is relatively simple: in
shrink_zone()we can check how many pages we have already freed, direct reclaim tasks break out of the scanning loop if they have already freed enough pages and have reached a lower priority level.However, in order to do this we do need to know how many pages we already freed, so move
nr_reclaimedintoscan_control.Signed-off-by Rik van Riel <[email protected]>---
Kosaki, this should address the zone scanning pressure issue.
Quoted 5 lines
Quoted 2 lines
hmmmm. I still don't like the behavior when priority==DEF_PRIORITY. but I also should explain by code and benchmark.
Well, the behaviour when priority==DEF_PRIORITY is the same as the kernel's behaviour without the patch...
Yes, but I think it decrease this patch's valueable...
Quoted 3 lines
Quoted 1 line
therefore, I'll try to mesure this patch in this week.
Looking forward to it.
thank you.
--
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>
Hi
I mesured some data in this week and I got some interesting data.
Quoted 6 lines
Quoted 1 line
Kosaki, this should address the zone scanning pressure issue.
hmmmm. I still don't like the behavior when priority==DEF_PRIORITY. but I also should explain by code and benchmark.
therefore, I'll try to mesure this patch in this week.
1. many # of process reclaiming at that time
I mesure ten times following bench.
$ hackbench 140 process 300
rc6+stream: 2.6.28-rc6 +
vmscan-evict-streaming-io-first.patch (in -mm)
rvr: above + Rik's bailing out patch kosaki: above + kosaki modify (attached the last in this mail)
result (unit: second)
rc6+stream rvr +kosaki patch
-----------------------------------------------------------
175.457 62.514 104.87 168.409 225.698 133.128 154.658 114.694 194.867 46.148 179.108 11.82 289.575 111.08 60.779 146.871 189.796 86.515 305.036 114.124 54.009 225.21 112.999 273.841 224.674 227.842 166.547 118.071 81.869 84.431 ------------------------------------------
avg 185.4109 141.9724 117.0807
std 74.18484 55.93676126 73.28439987
min 46.148 62.514 11.82
max 305.036 227.842 273.841
OK.
Rik patch improve about 30% and my patch improve 20% more. totally, We got about 50% improvement.
2. "communicate each other application" conflict the other
console A
$ dbench 100
console B
$ hackbench 130 process 300
hackbench result (unit :second)
rc6+stream rvr +kosaki ==================================================== 588.74 57.084 139.448 569.876 325.063 52.233 427.078 295.259 53.492 65.264 132.873 59.009 136.636 136.367 319.115 221.538 76.352 187.937 244.881 125.774 158.846 37.523 115.77 122.17 182.485 382.376 105.195 273.983 299.577 130.478 ----------------------------------------
avg 274.8004 194.6495 132.7923
std 184.4902365 111.5699478 75.88299814
min 37.523 57.084 52.233
max 588.74 382.376 319.115
That's more interesting.
-rc6 reclaim victory on min score. but also it has worst max score. why?
traditional reclaim assume following two case is equivalent.
case (1)
- task (a) spent 1 sec for reclaim.
- task (b) spent 1 sec for reclaim.
- task (c) spent 1 sec for reclaim.
case (2)
- task (a) spent 3 sec for reclaim.
- task (b) spent 0 sec for reclaim.
- task (c) spent 0 sec for reclaim.
However, when these task comminicate each other, it isn't correct.
if task (2)-(a) is dbench process, ok, you are lucky. dbench process don't comminicate each other. that's performance is decided from avarage performance.
one process slowdown don't become system slowdown.
then, hackbench and dbench get both good result.
In the other hand, if task (2)-(a) is hackbench process, you are unlucky. hackbench process communicate each other.
then the performance is decided slowest process.
then, hackbench performance dramatically decreased although dbench performance almost don't increased.
Therefore, I think case (1) is better.
So, rik patch and my patch improve perfectly different reclaim aspect. In general, kernel reclaim processing has several key goals.
(1) if system has droppable cache, system shouldn't happen oom kill.
(2) if system has avaiable swap space, system shouldn't happen oom kill as poosible as.
(3) if system has enough free memory, system shouldn't reclaim any page at all.
(4) if memory pressure is lite, system shouldn't cause heavy reclaim latency to application.
rik patch improve (3), my (this mail) modification improve (4).
BTW, reclaim throttle patch has one another improvement likes Hanns's "vmscan: serialize aggressive reclaimers" patch. actually, rik patch improvement (3). but it isn't perfect.
if 10000 thread call reclaim at that time, system reclaim 32*10000 pages. it is definitly too much.
but it is obviously offtopic :)
Rik, could you please merge my modify into your patch?
======
In past, HPC guys want to improve lite reclaim latency multiple times. (e.g. http://marc.info/?l=linux-mm&m=121418258514542&w=2)
because their workload has following characteristics.
- their workload make many process or many thread.
- typically, write() is called at job ending phase. then, many file cache isn't reused.
- In their parallel job, any process comminicate each other. then, system performance is decide from slowest thread. then, large reclaim latency decrease system performance directly.
Actually, kswapd background reclaim and direct reclaim have perfectly different purpose and goal.
background reclaim
- kswapd don't need latency overhead reducing.
it isn't observe from end user.
- kswapd shoudn't only increase free pages, but also should zone balancing.
foreground reclaim
- it used application task context.
- as possible as, it shouldn't increase latency overhead.
- this reclaiming purpose is to make the memory for _own_ taks. for other tasks memory don't need to concern.
kswap does it.
Almost developer don't payed attention for HPC in past. However, in these days, # of cpus increase rapidly. and parallel processing technique become commonly. (e.g. now, gcc has OpenMP feature support directly)
Therefore, we shouldn't ignore parallel application modern days.
o remove priority==DEF_PRIORITY condision
o shrink_zones() also should have bailing out feature.
--- mm/vmscan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
mm/vmscan.c +3 -1
@@ -1469,7 +1469,7 @@ static void shrink_zone(int priority, st* freeing target can get unreasonably large. */ if (sc->nr_reclaimed > sc->swap_cluster_max && - priority <DEF_PRIORITY && !current_is_kswapd ()) + !current_is_kswapd ())break ; }
@@ -1534,6 +1534,8 @@ static void shrink_zones(int priority, s }shrink_zone (priority, zone, sc); +if (sc->nr_reclaimed > sc->swap_cluster_max) +break ; } }
--
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 6 lines · KOSAKI Motohiro
Hi
I mesured some data in this week and I got some interesting data.
Rik patch improve about 30% and my patch improve 20% more. totally, We got about 50% improvement.
Very interesting indeed! I did not know there was this easy
a reproducer of the problem that my patch is trying to solve.
Quoted 6 lines
rc6+stream rvr +kosaki ----------------------------------------avg 274.8004 194.6495 132.7923
std 184.4902365 111.5699478 75.88299814
min 37.523 57.084 52.233
max 588.74 382.376 319.115
Impressive.
Quoted 11 lines
So, rik patch and my patch improve perfectly different reclaim aspect. In general, kernel reclaim processing has several key goals.
(1) if system has droppable cache, system shouldn't happen oom kill.
(2) if system has avaiable swap space, system shouldn't happen oom kill as poosible as.
(3) if system has enough free memory, system shouldn't reclaim any page at all.
(4) if memory pressure is lite, system shouldn't cause heavy reclaim latency to application.
Quoted 1 line
rik patch improve (3), my (this mail) modification improve (4).
Actually, to achieve (3) we would want to skip zones with way more than enough free memory in shrink_zones(). Kswapd already skips zones like this in shrink_pgdat(), so we definately want this change:
@@ -1519,6 +1519,9 @@ static void shrink_zones(int priority, s
if (zone_is_all_unreclaimable(zone) &&
priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */
+ if (zone_watermark_ok(zone, order, 4*zone->pages_high,
+ end_zone, 0))
+ continue; /* Lots free already */
sc->all_unreclaimable = 0;
} else {
/*I'm sending a patch with this right now :)
Quoted 9 lines
Actually, kswapd background reclaim and direct reclaim have perfectly different purpose and goal.
background reclaim
- kswapd don't need latency overhead reducing.
it isn't observe from end user.
- kswapd shoudn't only increase free pages, but also should zone balancing.
Quoted 6 lines
foreground reclaim
- it used application task context.
- as possible as, it shouldn't increase latency overhead.
- this reclaiming purpose is to make the memory for _own_ taks. for other tasks memory don't need to concern.
kswap does it.
I am not entirely convinced that breaking out of the loop early in a zone is not harmful for direct reclaimers. Maybe it works fine, maybe it won't.
Or maybe direct reclaimers should start scanning the largest zone first, so your change can be done with the lowest risk possible?
Having said that, the 20% additional performance achieved with your changes is impressive.
Quoted 1 line
o remove priority==DEF_PRIORITY condision
This one could definately be worth considering.
However, looking at the changeset that was backed out in the early 2.6 series suggests that it may not be the best idea.
Quoted 1 line
o
shrink_zones()also should have bailing out feature.
This one is similar. What are the downsides of skipping a zone entirely, when that zone has pages that should be freed?
If it can lead to the VM reclaiming new pages from one zone, while leaving old pages from another zone in memory, we can greatly reduce the caching efficiency of the page cache.
Quoted 25 lines
--- mm/vmscan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)Index:
b/mm/vmscan.c
===================================================================mm/vmscan.c +3
-1@@ -1469,7 +1469,7 @@ static void shrink_zone(int priority, st* freeing target can get unreasonably large. */ if (sc->nr_reclaimed > sc->swap_cluster_max && - priority <DEF_PRIORITY && !current_is_kswapd ()) + !current_is_kswapd ())break ; }@@ -1534,6 +1534,8 @@ static void shrink_zones(int priority, s }shrink_zone (priority, zone, sc); +if (sc->nr_reclaimed > sc->swap_cluster_max) +break ; } }
Signature · 7 lines
All rights reversed. -- 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 30 lines
Quoted 11 lines
So, rik patch and my patch improve perfectly different reclaim aspect. In general, kernel reclaim processing has several key goals.
(1) if system has droppable cache, system shouldn't happen oom kill.
(2) if system has avaiable swap space, system shouldn't happen oom kill as poosible as.
(3) if system has enough free memory, system shouldn't reclaim any page at all.
(4) if memory pressure is lite, system shouldn't cause heavy reclaim latency to application.Quoted 1 line
rik patch improve (3), my (this mail) modification improve (4).
Actually, to achieve (3) we would want to skip zones with way more than enough free memory in
shrink_zones(). Kswapd already skips zones like this inshrink_pgdat(), so we definately want this change:(quoted diff) +3
-0@@ -1519,6 +1519,9 @@ static void shrink_zones(int priority, s if (zone_is_all_unreclaimable(zone) && priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ + if (zone_watermark_ok(zone, order, 4*zone->pages_high, + end_zone, 0)) + continue; /* Lots free already */ sc->all_unreclaimable = 0; } else {/*
Quoted 1 line
I'm sending a patch with this right now :)
please wait few days.
Actually, I made similar patch half year ago. but I droped it because I observe performance degression.
but my recall isn't clear.
I should mesure it again.
My guessing is,zone_waterwark_ok() is very slow function, it doesn't only check the number of the free memory, but also check memory fragmentation. So, it is called when lite memory pressure, we violate above rule (4).
Quoted 33 lines
Quoted 9 lines
Actually, kswapd background reclaim and direct reclaim have perfectly different purpose and goal.
background reclaim
- kswapd don't need latency overhead reducing.
it isn't observe from end user.
- kswapd shoudn't only increase free pages, but also should zone balancing.Quoted 6 lines
foreground reclaim
- it used application task context.
- as possible as, it shouldn't increase latency overhead.
- this reclaiming purpose is to make the memory for _own_ taks. for other tasks memory don't need to concern.
kswap does it.I am not entirely convinced that breaking out of the loop early in a zone is not harmful for direct reclaimers. Maybe it works fine, maybe it won't.
Or maybe direct reclaimers should start scanning the largest zone first, so your change can be done with the lowest risk possible?
Having said that, the 20% additional performance achieved with your changes is impressive.
Quoted 1 line
o remove priority==DEF_PRIORITY condision
This one could definately be worth considering.
However, looking at the changeset that was backed out in the early 2.6 series suggests that it may not be the best idea.
Quoted 8 lines
Quoted 1 line
o
shrink_zones()also should have bailing out feature.This one is similar. What are the downsides of skipping a zone entirely, when that zone has pages that should be freed?
If it can lead to the VM reclaiming new pages from one zone, while leaving old pages from another zone in memory, we can greatly reduce the caching efficiency of the page cache.
I think I can explain logically.
At first, please see below ML archive url.
it describe why akpm's "vmscan.c: dont reclaim too many pages" was dropped.
Again, old akpm patch restrict direct reclaim and background reclaim. Therefore that url's discussion didn't separate two things too. but your and mine restrict direct reclaim only.
At that time, Marcelo Tosatti reported akpm patch cause reclaim imbalancing by FFSB benchmark.
I mesured ffsb on 2.6.28-rc6 and our patch.
mesured machine spec:
CPU: IA64 x 8
MEM
Node0: DMA ZONE: 2GB
NORMAL ZONE: 2GB
Node1: DMA ZONE: 4GB
-----------------
total 8GB
used configuration file (the same of marcelo's conf)
---------------------------------------------------
directio=0
time=300
[filesystem0]
location=/mnt/sdb1/kosaki/ffsb
num_files=20
num_dirs=10
max_filesize=91534338
min_filesize=65535
[end0]
[threadgroup0]
num_threads=10
write_size=2816
write_blocksize=4096
read_size=2816
read_blocksize=4096
create_weight=100
write_weight=30
read_weight=100
[end0]
--------------------------------------------------------
result:
------------ 2.6.28-rc6 ----------------------------------
pgscan_kswapd_dma 10624pgscan_kswapd_normal 20640
-> normal/dma ratio 20640 / 10624 = 1.9
pgscan_direct_dma 576pgscan_direct_normal 2528
-> normal/dma ratio 2528 / 576 = 4.38
kswapd+direct dma 11200
kswapd+direct normal 23168
-> normal/dma ratio 2.0
------------ rvr bail out ---------------------------------
pgscan_kswapd_dma 15552pgscan_kswapd_normal 31936
-> normal/dma ratio 2.05
pgscan_direct_dma 1216pgscan_direct_normal 3968
-> normal/dma ratio 3.26
kswapd+direct dma 16768
kswapd+direct normal 35904
-> normal/dma ratio 2.1
------------ +kosaki ---------------------------------
pgscan_kswapd_dma 14208pgscan_kswapd_normal 31616
-> normal/dma ratio 31616/14208 = 2.25
pgscan_direct_dma 1024pgscan_direct_normal 3328
-> normal/dma ratio 3328/1024 = 3.25
kswapd+direct dma 15232
kswapd+direct normal 34944
-> normal/dma ratio 2.2
----------------------------------------------------------
The result talk about three things.
- rvr and mine patch increase direct reclaim imbalancing, indeed.
- However, background reclaim scanning is _very_ much than direct reclaim. Then, direct reclaim imbalancing is ignorable on the big view. rvr patch doesn't reintroduce zone imbalancing issue.
- rvr's priority==DEF_PRIORITY condition checking doesn't improve zone balancing at all.
we can drop it.
Again, I believe my patch improve vm scanning totally.
Any comments?
Andrew, I hope add this mesurement result to rvr bailing out patch description too. Please let me know what I should do.
--
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 · KOSAKI Motohiro
The result talk about three things.
- rvr and mine patch increase direct reclaim imbalancing, indeed.
- However, background reclaim scanning is _very_ much than direct reclaim. Then, direct reclaim imbalancing is ignorable on the big view. rvr patch doesn't reintroduce zone imbalancing issue.
- rvr's priority==DEF_PRIORITY condition checking doesn't improve zone balancing at all.
we can drop it.
Quoted 3 lines
Again, I believe my patch improve vm scanning totally.
Any comments?
Reclaiming is very easy when the workload is just page cache, because the application will be throttled when too many page cache pages are dirty.
When using mmap or memory hogs writing to swap, applications will not be throttled by the "too many dirty pages" logic, but may instead end up being throttled in the direct reclaim path instead.
At that point direct reclaim may become a lot more common, making the imbalance more significant.
I'll run a few tests.
Quoted 1 line
Andrew, I hope add this mesurement result to rvr bailing out patch description too.
So far the performance numbers you have measured are very encouraging and do indeed suggest that the priority==DEF_PRIORITY thing does not make a difference.
Signature · 7 lines
All rights reversed. -- 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 11 lines
Reclaiming is very easy when the workload is just page cache, because the application will be throttled when too many page cache pages are dirty.
When using mmap or memory hogs writing to swap, applications will not be throttled by the "too many dirty pages" logic, but may instead end up being throttled in the direct reclaim path instead.
At that point direct reclaim may become a lot more common, making the imbalance more significant.
fair enough.
Quoted 1 line
I'll run a few tests.
Great.
I'm looking for your mail :)
Quoted 5 lines
Quoted 1 line
Andrew, I hope add this mesurement result to rvr bailing out patch description too.
So far the performance numbers you have measured are very encouraging and do indeed suggest that the priority==DEF_PRIORITY thing does not make a difference.
thank you.
I believe reclaim latency reducing doesn't only improve hpc, but also improve several multimedia and desktop application.
--
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>
PATCH 1/1 vmscan: improve reclaim throuput to bail out patch
Hi
I evaluate rvr bailout and skip-freeing patch in this week conteniously. I'd like to dump first output here.
Rik, could you please review following?
==
vmscan bail out patch move nr_reclaimed variable to struct scan_control. Unfortunately, indirect access can easily happen cache miss. More unfortunately, Some architecture (e.g. ia64) don't access global variable so fast.
if heavy memory pressure happend, that's ok.
cache miss already plenty. it is not observable.
but, if memory pressure is lite, performance degression is obserbable.
I compared following three pattern (it was mesured 10 times each)
hackbench 125 process 3000
hackbench 130 process 3000
hackbench 135 process 3000
2.6.28-rc6 bail-out
125 130 135 125 130 135
==============================================================
71.866 75.86 81.274 93.414 73.254 193.382
74.145 78.295 77.27 74.897 75.021 80.17
70.305 77.643 75.855 70.134 77.571 79.896
74.288 73.986 75.955 77.222 78.48 80.619
72.029 79.947 78.312 75.128 82.172 79.708
71.499 77.615 77.042 74.177 76.532 77.306
76.188 74.471 83.562 73.839 72.43 79.833
73.236 75.606 78.743 76.001 76.557 82.726
69.427 77.271 76.691 76.236 79.371 103.189
72.473 76.978 80.643 69.128 78.932 75.736avg 72.545 76.767 78.534 76.017 77.03 93.256
std 1.89 1.71 2.41 6.29 2.79 34.16
min 69.427 73.986 75.855 69.128 72.43 75.736
max 76.188 79.947 83.562 93.414 82.172 193.382
about 4-5% degression.
Then, this patch introduce temporal local variable.
result:
2.6.28-rc6 this patch
num 125 130 135 125 130 135
============================================================== 71.866 75.86 81.274 67.302 68.269 77.161 74.145 78.295 77.27 72.616 72.712 79.06 70.305 77.643 75.855 72.475 75.712 77.735 74.288 73.986 75.955 69.229 73.062 78.814 72.029 79.947 78.312 71.551 74.392 78.564 71.499 77.615 77.042 69.227 74.31 78.837 76.188 74.471 83.562 70.759 75.256 76.6 73.236 75.606 78.743 69.966 76.001 78.464 69.427 77.271 76.691 69.068 75.218 80.321 72.473 76.978 80.643 72.057 77.151 79.068
avg 72.545 76.767 78.534 70.425 74.2083 78.462
std 1.89 1.71 2.41 1.66 2.34 1.00
min 69.427 73.986 75.855 67.302 68.269 76.6
max 76.188 79.947 83.562 72.616 77.151 80.321
OK. the degression is disappeared.
--- mm/vmscan.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
mm/vmscan.c +9 -6
@@ -1418,6 +1418,8 @@ static void shrink_zone(int priority, stunsigned long nr_to_scan;unsigned long percent[2 ];/* anon @ 0; file @ 1 */ enum lru_list l; +unsigned long nr_reclaimed = sc->nr_reclaimed; +unsigned long swap_cluster_max = sc->swap_cluster_max;get_scan_ratio (zone, sc, percent);
@@ -1433,7 +1435,7 @@ static void shrink_zone(int priority, st } zone->lru[l].nr_scan += scan; nr[l] = zone->lru[l].nr_scan; -if (nr[l] >= sc->swap_cluster_max) +if (nr[l] >= swap_cluster_max) zone->lru[l].nr_scan =0 ;else nr[l] =0 ;
@@ -1452,12 +1454,11 @@ static void shrink_zone(int priority, st nr[LRU_INACTIVE_FILE]) {for_each_evictable_lru (l) {if (nr[l]) { - nr_to_scan =min (nr[l], - (unsigned long )sc->swap_cluster_max); + nr_to_scan =min (nr[l], swap_cluster_max); nr[l] -= nr_to_scan; - sc->nr_reclaimed +=shrink_list (l, nr_to_scan, - zone, sc, priority); + nr_reclaimed +=shrink_list (l, nr_to_scan, + zone, sc, priority); } }/*
@@ -1468,11 +1469,13 @@ static void shrink_zone(int priority, st* with multiple processes reclaiming pages, the total * freeing target can get unreasonably large. */ -if (sc->nr_reclaimed > sc->swap_cluster_max && +if (nr_reclaimed > swap_cluster_max && priority <DEF_PRIORITY && !current_is_kswapd ())break ; } + sc->nr_reclaimed = nr_reclaimed; +/* * Even if we did not try to evict anon pages at all, we want to * rebalance the anon lru active/inactive ratio.
--
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>
Re: [PATCH] vmscan: improve reclaim throuput to bail out patch
Quoted 7 lines · KOSAKI Motohiro
Hi
I evaluate rvr bailout and skip-freeing patch in this week conteniously. I'd like to dump first output here.
Quoted 6 lines
Rik, could you please review following?
==
vmscan bail out patch movenr_reclaimedvariable to structscan_control. Unfortunately, indirect access can easily happen cache miss. More unfortunately, Some architecture (e.g. ia64) don't access global variable so fast.
That is amazing. Especially considering that the scan_control is a local variable on the stack.
Quoted 10 lines
if heavy memory pressure happend, that's ok.
cache miss already plenty. it is not observable.but, if memory pressure is lite, performance degression is obserbable.
about 4-5% degression.
Then, this patch introduce temporal local variable.
OK. the degression is disappeared.
I can't argue with the numbers, though :)
Maybe all the scanning we do ends up evicting the cache lines with the scan_control struct in it from the fast part of the CPU cache?
Quoted 1 line
Signed-off-by KOSAKI Motohiro <[email protected]>
Signature · 7 lines
All rights reversed. -- 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>
Re: [PATCH] vmscan: improve reclaim throuput to bail out patch
Quoted 12 lines
Quoted 11 lines
I evaluate rvr bailout and skip-freeing patch in this week conteniously. I'd like to dump first output here.
Rik, could you please review following?
==
vmscan bail out patch movenr_reclaimedvariable to structscan_control. Unfortunately, indirect access can easily happen cache miss. More unfortunately, Some architecture (e.g. ia64) don't access global variable so fast.
Quoted 2 lines
That is amazing. Especially considering that the
scan_controlis a local variable on the stack.
Ahhhhh, I did want to write "indirect access(or likes global variables)", but my brain was sucked. sorry.
I'll post description fixed version soon. thanks.
Quoted 9 lines
Quoted 8 lines
if heavy memory pressure happend, that's ok.
cache miss already plenty. it is not observable.but, if memory pressure is lite, performance degression is obserbable.
about 4-5% degression.
Then, this patch introduce temporal local variable.
Quoted 7 lines
Quoted 1 line
OK. the degression is disappeared.
I can't argue with the numbers, though :)
Maybe all the scanning we do ends up evicting the cache lines with the
scan_controlstruct in it from the fast part of the CPU cache?
Yeah, I think so.
Quoted 4 lines
Quoted 2 lines
Signed-off-by KOSAKI Motohiro <[email protected]>Acked-by Rik van Riel <[email protected]>
--
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>
PATCH 1/1 vmscan: improve reclaim throuput to bail out patch take2
The vmscan bail out patch move nr_reclaimed variable to struct scan_control. Unfortunately, indirect access can easily happen cache miss.
if heavy memory pressure happend, that's ok.
cache miss already plenty. it is not observable.
but, if memory pressure is lite, performance degression is obserbable.
I compared following three pattern (it was mesured 10 times each)
hackbench 125 process 3000
hackbench 130 process 3000
hackbench 135 process 3000
2.6.28-rc6 bail-out
125 130 135 125 130 135
==============================================================
71.866 75.86 81.274 93.414 73.254 193.382
74.145 78.295 77.27 74.897 75.021 80.17
70.305 77.643 75.855 70.134 77.571 79.896
74.288 73.986 75.955 77.222 78.48 80.619
72.029 79.947 78.312 75.128 82.172 79.708
71.499 77.615 77.042 74.177 76.532 77.306
76.188 74.471 83.562 73.839 72.43 79.833
73.236 75.606 78.743 76.001 76.557 82.726
69.427 77.271 76.691 76.236 79.371 103.189
72.473 76.978 80.643 69.128 78.932 75.736avg 72.545 76.767 78.534 76.017 77.03 93.256
std 1.89 1.71 2.41 6.29 2.79 34.16
min 69.427 73.986 75.855 69.128 72.43 75.736
max 76.188 79.947 83.562 93.414 82.172 193.382
about 4-5% degression.
Then, this patch introduce temporal local variable.
result:
2.6.28-rc6 this patch
num 125 130 135 125 130 135
============================================================== 71.866 75.86 81.274 67.302 68.269 77.161 74.145 78.295 77.27 72.616 72.712 79.06 70.305 77.643 75.855 72.475 75.712 77.735 74.288 73.986 75.955 69.229 73.062 78.814 72.029 79.947 78.312 71.551 74.392 78.564 71.499 77.615 77.042 69.227 74.31 78.837 76.188 74.471 83.562 70.759 75.256 76.6 73.236 75.606 78.743 69.966 76.001 78.464 69.427 77.271 76.691 69.068 75.218 80.321 72.473 76.978 80.643 72.057 77.151 79.068
avg 72.545 76.767 78.534 70.425 74.2083 78.462
std 1.89 1.71 2.41 1.66 2.34 1.00
min 69.427 73.986 75.855 67.302 68.269 76.6
max 76.188 79.947 83.562 72.616 77.151 80.321
OK. the degression is disappeared.
--- mm/vmscan.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
mm/vmscan.c +9 -6
@@ -1418,6 +1418,8 @@ static void shrink_zone(int priority, stunsigned long nr_to_scan;unsigned long percent[2 ];/* anon @ 0; file @ 1 */ enum lru_list l; +unsigned long nr_reclaimed = sc->nr_reclaimed; +unsigned long swap_cluster_max = sc->swap_cluster_max;get_scan_ratio (zone, sc, percent);
@@ -1433,7 +1435,7 @@ static void shrink_zone(int priority, st } zone->lru[l].nr_scan += scan; nr[l] = zone->lru[l].nr_scan; -if (nr[l] >= sc->swap_cluster_max) +if (nr[l] >= swap_cluster_max) zone->lru[l].nr_scan =0 ;else nr[l] =0 ;
@@ -1452,12 +1454,11 @@ static void shrink_zone(int priority, st nr[LRU_INACTIVE_FILE]) {for_each_evictable_lru (l) {if (nr[l]) { - nr_to_scan =min (nr[l], - (unsigned long )sc->swap_cluster_max); + nr_to_scan =min (nr[l], swap_cluster_max); nr[l] -= nr_to_scan; - sc->nr_reclaimed +=shrink_list (l, nr_to_scan, - zone, sc, priority); + nr_reclaimed +=shrink_list (l, nr_to_scan, + zone, sc, priority); } }/*
@@ -1468,11 +1469,13 @@ static void shrink_zone(int priority, st* with multiple processes reclaiming pages, the total * freeing target can get unreasonably large. */ -if (sc->nr_reclaimed > sc->swap_cluster_max && +if (nr_reclaimed > swap_cluster_max && priority <DEF_PRIORITY && !current_is_kswapd ())break ; } + sc->nr_reclaimed = nr_reclaimed; +/* * Even if we did not try to evict anon pages at all, we want to * rebalance the anon lru active/inactive ratio.
--
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>
Re: [PATCH] vmscan: improve reclaim throuput to bail out patch take2
Hi, Kosaki-san.
It's a great improvement with only one variable than I expected. :) What is your test environment ? (CPU, L1, L2 cache size and so ) Just out of curiosity.
Quoted 134 lines · KOSAKI Motohiro
The vmscan bail out patch move
nr_reclaimedvariable to structscan_control. Unfortunately, indirect access can easily happen cache miss.if heavy memory pressure happend, that's ok.
cache miss already plenty. it is not observable.but, if memory pressure is lite, performance degression is obserbable.
I compared following three pattern (it was mesured 10 times each)
hackbench 125 process 3000
hackbench 130 process 3000
hackbench 135 process 30002.6.28-rc6 bail-out 125 130 135 125 130 135 ============================================================== 71.866 75.86 81.274 93.414 73.254 193.382 74.145 78.295 77.27 74.897 75.021 80.17 70.305 77.643 75.855 70.134 77.571 79.896 74.288 73.986 75.955 77.222 78.48 80.619 72.029 79.947 78.312 75.128 82.172 79.708 71.499 77.615 77.042 74.177 76.532 77.306 76.188 74.471 83.562 73.839 72.43 79.833 73.236 75.606 78.743 76.001 76.557 82.726 69.427 77.271 76.691 76.236 79.371 103.189 72.473 76.978 80.643 69.128 78.932 75.736avg 72.545 76.767 78.534 76.017 77.03 93.256 std 1.89 1.71 2.41 6.29 2.79 34.16 min 69.427 73.986 75.855 69.128 72.43 75.736 max 76.188 79.947 83.562 93.414 82.172 193.382about 4-5% degression.
Then, this patch introduce temporal local variable.
result:
2.6.28-rc6 this patch
num 125 130 135 125 130 135
============================================================== 71.866 75.86 81.274 67.302 68.269 77.161 74.145 78.295 77.27 72.616 72.712 79.06 70.305 77.643 75.855 72.475 75.712 77.735 74.288 73.986 75.955 69.229 73.062 78.814 72.029 79.947 78.312 71.551 74.392 78.564 71.499 77.615 77.042 69.227 74.31 78.837 76.188 74.471 83.562 70.759 75.256 76.6 73.236 75.606 78.743 69.966 76.001 78.464 69.427 77.271 76.691 69.068 75.218 80.321 72.473 76.978 80.643 72.057 77.151 79.068avg 72.545 76.767 78.534 70.425 74.2083 78.462 std 1.89 1.71 2.41 1.66 2.34 1.00 min 69.427 73.986 75.855 67.302 68.269 76.6 max 76.188 79.947 83.562 72.616 77.151 80.321OK. the degression is disappeared.
Signed-off-by KOSAKI Motohiro <[email protected]>Acked-by Rik van Riel <[email protected]>--- mm/vmscan.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)Index:
b/mm/vmscan.c
===================================================================mm/vmscan.c +9
-7@@ -1418,6 +1418,8 @@ static void shrink_zone(int priority, stunsigned long nr_to_scan;unsigned long percent[2 ];/* anon @ 0; file @ 1 */ enum lru_list l; +unsigned long nr_reclaimed = sc->nr_reclaimed; +unsigned long swap_cluster_max = sc->swap_cluster_max;get_scan_ratio (zone, sc, percent);@@ -1433,7 +1435,7 @@ static void shrink_zone(int priority, st } zone->lru[l].nr_scan += scan; nr[l] = zone->lru[l].nr_scan; -if (nr[l] >= sc->swap_cluster_max) +if (nr[l] >= swap_cluster_max) zone->lru[l].nr_scan =0 ;else nr[l] =0 ;@@ -1452,12 +1454,11 @@ static void shrink_zone(int priority, st nr[LRU_INACTIVE_FILE]) {for_each_evictable_lru (l) {if (nr[l]) { - nr_to_scan =min (nr[l], - (unsigned long )sc->swap_cluster_max); + nr_to_scan =min (nr[l], swap_cluster_max); nr[l] -= nr_to_scan; - sc->nr_reclaimed +=shrink_list (l, nr_to_scan, - zone, sc, priority); + nr_reclaimed +=shrink_list (l, nr_to_scan, + zone, sc, priority); } }/* @@ -1468,11 +1469,13 @@ static void shrink_zone(int priority, st* with multiple processes reclaiming pages, the total * freeing target can get unreasonably large. */ -if (sc->nr_reclaimed > sc->swap_cluster_max && +if (nr_reclaimed > swap_cluster_max && priority <DEF_PRIORITY && !current_is_kswapd ())break ; } + sc->nr_reclaimed = nr_reclaimed; +/* * Even if we did not try to evict anon pages at all, we want to * rebalance the anon lru active/inactive ratio. -- 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>
Signature · 8 lines
Kinds regards, MinChan Kim -- 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>
Re: [PATCH] vmscan: improve reclaim throuput to bail out patch take2
Hi
Quoted 5 lines
Hi, Kosaki-san.
It's a great improvement with only one variable than I expected. :) What is your test environment ? (CPU, L1, L2 cache size and so ) Just out of curiosity.
CPU: ia64x8
L1: 16KB
L2: 512KB
L3: 24MB
--
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>
Andrew Morton
maintainerRe: [PATCH] vmscan: improve reclaim throuput to bail out patch take2
In reply to KOSAKI MotohiroQuoted 57 lines · On Thu, 4 Dec 2008 10:28:39 +0900 (JST) KOSAKI Motohiro…
The vmscan bail out patch move
nr_reclaimedvariable to structscan_control. Unfortunately, indirect access can easily happen cache miss.if heavy memory pressure happend, that's ok.
cache miss already plenty. it is not observable.but, if memory pressure is lite, performance degression is obserbable.
I compared following three pattern (it was mesured 10 times each)
hackbench 125 process 3000
hackbench 130 process 3000
hackbench 135 process 30002.6.28-rc6 bail-out 125 130 135 125 130 135 ============================================================== 71.866 75.86 81.274 93.414 73.254 193.382 74.145 78.295 77.27 74.897 75.021 80.17 70.305 77.643 75.855 70.134 77.571 79.896 74.288 73.986 75.955 77.222 78.48 80.619 72.029 79.947 78.312 75.128 82.172 79.708 71.499 77.615 77.042 74.177 76.532 77.306 76.188 74.471 83.562 73.839 72.43 79.833 73.236 75.606 78.743 76.001 76.557 82.726 69.427 77.271 76.691 76.236 79.371 103.189 72.473 76.978 80.643 69.128 78.932 75.736avg 72.545 76.767 78.534 76.017 77.03 93.256
std 1.89 1.71 2.41 6.29 2.79 34.16
min 69.427 73.986 75.855 69.128 72.43 75.736
max 76.188 79.947 83.562 93.414 82.172 193.382about 4-5% degression.
Then, this patch introduce temporal local variable.
result:
2.6.28-rc6 this patch
num 125 130 135 125 130 135
============================================================== 71.866 75.86 81.274 67.302 68.269 77.161 74.145 78.295 77.27 72.616 72.712 79.06 70.305 77.643 75.855 72.475 75.712 77.735 74.288 73.986 75.955 69.229 73.062 78.814 72.029 79.947 78.312 71.551 74.392 78.564 71.499 77.615 77.042 69.227 74.31 78.837 76.188 74.471 83.562 70.759 75.256 76.6 73.236 75.606 78.743 69.966 76.001 78.464 69.427 77.271 76.691 69.068 75.218 80.321 72.473 76.978 80.643 72.057 77.151 79.068
Quoted 8 lines
avg 72.545 76.767 78.534 70.425 74.2083 78.462
std 1.89 1.71 2.41 1.66 2.34 1.00
min 69.427 73.986 75.855 67.302 68.269 76.6
max 76.188 79.947 83.562 72.616 77.151 80.321OK. the degression is disappeared.
Yes, this is a very surprising result. Suspicious, in fact.
Quoted 51 lines
Signed-off-by KOSAKI Motohiro <[email protected]>Acked-by Rik van Riel <[email protected]>--- mm/vmscan.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)Index:
b/mm/vmscan.c
===================================================================mm/vmscan.c +6
-6@@ -1418,6 +1418,8 @@ static void shrink_zone(int priority, stunsigned long nr_to_scan;unsigned long percent[2 ];/* anon @ 0; file @ 1 */ enum lru_list l; +unsigned long nr_reclaimed = sc->nr_reclaimed; +unsigned long swap_cluster_max = sc->swap_cluster_max;get_scan_ratio (zone, sc, percent);@@ -1433,7 +1435,7 @@ static void shrink_zone(int priority, st } zone->lru[l].nr_scan += scan; nr[l] = zone->lru[l].nr_scan; -if (nr[l] >= sc->swap_cluster_max) +if (nr[l] >= swap_cluster_max) zone->lru[l].nr_scan =0 ;else nr[l] =0 ;@@ -1452,12 +1454,11 @@ static void shrink_zone(int priority, st nr[LRU_INACTIVE_FILE]) {for_each_evictable_lru (l) {if (nr[l]) { - nr_to_scan =min (nr[l], - (unsigned long )sc->swap_cluster_max); + nr_to_scan =min (nr[l], swap_cluster_max); nr[l] -= nr_to_scan; - sc->nr_reclaimed +=shrink_list (l, nr_to_scan, - zone, sc, priority); + nr_reclaimed +=shrink_list (l, nr_to_scan, + zone, sc, priority); } }/* @@ -1468,11 +1469,13 @@ static void shrink_zone(int priority, st* with multiple processes reclaiming pages, the total * freeing target can get unreasonably large. */ - if (sc->nr_reclaimed > sc->swap_cluster_max &&
mm/vmscan.c static void shrink_zone(int priority, st · line 1481
Quoted 10 lines
mm/vmscan.c +3
-0+if (nr_reclaimed > swap_cluster_max && priority <DEF_PRIORITY && !current_is_kswapd ())break ; } + sc->nr_reclaimed = nr_reclaimed; +/* * Even if we did not try to evict anon pages at all, we want to * rebalance the anon lru active/inactive ratio.
If this improved the throughput of direct-reclaim callers then one would expect it to make larger improvements for kswapd (assuming that all other things are equal for those tasks, which they are not).
What is your direct-reclaim to kswapd-reclaim ratio for that workload? (grep pgscan /proc/vmstat)
Does that patch make any change to the amount of CPU time which kswapd consumed?
Or you can not bother doing this work ;) The patch looks sensible anyway. It's just that the numbers look whacky.
--
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>
Re: [PATCH] vmscan: improve reclaim throuput to bail out patch take2
I think my last explain was too poor.
Quoted 7 lines
If this improved the throughput of direct-reclaim callers then one would expect it to make larger improvements for kswapd (assuming that all other things are equal for those tasks, which they are not).
What is your direct-reclaim to kswapd-reclaim ratio for that workload? (grep pgscan
/proc/vmstat)
because that benchmark is direct reclaim torturess workload.
/proc/vmstat changing was
<before>pgscan_kswapd_dma 1152pgscan_kswapd_normal 2400pgscan_kswapd_movable 0pgscan_direct_dma 32pgscan_direct_normal 512pgscan_direct_movable 0
<after>pgscan_kswapd_dma 3520pgscan_kswapd_normal 12160pgscan_kswapd_movable 0pgscan_direct_dma 10048pgscan_direct_normal 31904pgscan_direct_movable 0
-> kswapd:direct = 1 : 3.4
Why I test non typical extreame woakload?
I have two reason.
1. nobody want to regression although workload isn't typical.
2. if the patch can scale performance although extreme case, of cource it also can works well on light weight workload.
if my patch have any regression, it definityly is valueless. my patch only solve extreme case.
but I don't think it has.
Quoted 2 lines
Does that patch make any change to the amount of CPU time which kswapd consumed?
I don't mesure it yet.
but at least, top coomand didn't find any consumption increasing.
Quoted 3 lines
Or you can not bother doing this work ;) The patch looks sensible anyway. It's just that the numbers look whacky.
--
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 · Rik van Riel
When using mmap or memory hogs writing to swap, applications will not be throttled by the "too many dirty pages" logic, but may instead end up being throttled in the direct reclaim path instead.
The too many dirty pages logic will throttle applications dirtying mmapped pages these days.
--
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>
Review
Quoted 11 lines
(quoted diff) +11
-0+ /* + * On large memory systems, scan >> priority can become + * really large. This is fine for the starting priority; + * we want to put equal scanning pressure on each zone. + * However, if the VM has a harder time of freeing pages, + * with multiple processes reclaiming pages, the total + * freeing target can get unreasonably large. + */ + if (sc->nr_reclaimed > sc->swap_cluster_max && + sc->priority < DEF_PRIORITY && !current_is_kswapd()) + break;
typo.
this patch can't compile.
--- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/vmscan.c +1 -1
@@ -1469,7 +1469,7 @@ static void shrink_zone(int priority, st* freeing target can get unreasonably large. */ if (sc->nr_reclaimed > sc->swap_cluster_max && - sc->priority <DEF_PRIORITY && !current_is_kswapd ()) + priority <DEF_PRIORITY && !current_is_kswapd ())break ; }
--
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>
Johannes Weiner
maintainerRFC 1/1 vmscan: serialize aggressive reclaimers
In reply to Rik van RielSince we have to pull through a reclaim cycle once we commited to it, what do you think about serializing the lower priority levels completely?
The idea is that when one reclaimer has done a low priority level iteration with a huge reclaim target, chances are that succeeding reclaimers don't even need to drop to lower levels at all because enough memory has already been freed.
My testprogram maps and faults in a file that is about as large as my physical memory. Then it spawns off n processes that try allocate 1/2n of total memory in anon pages, i.e. half of it in sum. After it ran, I check how much memory has been reclaimed. But my zone sizes are too small to induce enormous reclaim targets so I don't see vast over-reclaims.
I have measured the time of other tests on an SMP machine with 4 cores and the following patch applied. I couldn't see any performance degradation. But since the bug is not triggerable here, I can not prove it helps the original problem, either.
The level where it starts serializing is chosen pretty arbitrarily. Suggestions welcome :)
Hannes
---
Prevent over-reclaiming by serializing direct reclaimers below a certain priority level.
Over-reclaiming happens when the sum of the reclaim targets of all reclaiming processes is larger than the sum of the needed free pages, thus leading to excessive eviction of more cache and anonymous pages than required.
A scan iteration over all zones can not be aborted intermittently when enough pages are reclaimed because that would mess up the scan balance between the zones. Instead, prevent that too many processes simultaneously commit themselves to lower priority level scans in the first place.
Chances are that after the exclusive reclaimer has finished, enough memory has been freed that succeeding scanners don't need to drop to lower priority levels at all anymore.
--- mm/vmscan.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
mm/vmscan.c +20 -0
@@ -35,6 +35,7 @@#include <linux/notifier.h> #include <linux/rwsem.h> #include <linux/delay.h> +#include <linux/wait.h> #include <linux/kthread.h> #include <linux/freezer.h> #include <linux/memcontrol.h>
@@ -42,6 +43,7 @@#include <linux/sysctl.h> #include <asm/tlbflush.h> +#include <asm/atomic.h> #include <asm/div64.h> #include <linux/swapops.h>
@@ -1546,10 +1548,15 @@ static unsigned long shrink_zones(int pr* returns: 0, if no pages reclaimed * else, the number of pages reclaimed */ + +static DECLARE_WAIT_QUEUE_HEAD (reclaim_wait); +static atomic_t reclaim_exclusive =ATOMIC_INIT (0 ); +static unsigned long do_try_to_free_pages (struct zonelist *zonelist,struct scan_control *sc) {int priority; +int exclusive =0 ;unsigned long ret =0 ;unsigned long total_scanned =0 ;unsigned long nr_reclaimed =0 ;
@@ -1580,6 +1587,14 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); +/* +* Serialize aggressive reclaimers +*/ +if (priority <=DEF_PRIORITY /2 && !exclusive) { +wait_event (reclaim_wait, + !atomic_cmpxchg (&reclaim_exclusive,0 ,1 )); + exclusive =1 ; + } nr_reclaimed +=shrink_zones (priority, zonelist, sc);/* * Don't shrink slabs when reclaiming memory from
@@ -1629,6 +1644,11 @@ out:if (priority <0 ) priority =0 ; +if (exclusive) { +atomic_set (&reclaim_exclusive,0 ); +wake_up (&reclaim_wait); + } +if (scan_global_lru (sc)) {for_each_zone_zonelist (zone, z, zonelist, high_zoneidx) {
Re: [rfc] vmscan: serialize aggressive reclaimers
Quoted 16 lines
Since we have to pull through a reclaim cycle once we commited to it, what do you think about serializing the lower priority levels completely?
The idea is that when one reclaimer has done a low priority level iteration with a huge reclaim target, chances are that succeeding reclaimers don't even need to drop to lower levels at all because enough memory has already been freed.
My testprogram maps and faults in a file that is about as large as my physical memory. Then it spawns off n processes that try allocate 1/2n of total memory in anon pages, i.e. half of it in sum. After it ran, I check how much memory has been reclaimed. But my zone sizes are too small to induce enormous reclaim targets so I don't see vast over-reclaims.
Quoted 4 lines
I have measured the time of other tests on an SMP machine with 4 cores and the following patch applied. I couldn't see any performance degradation. But since the bug is not triggerable here, I can not prove it helps the original problem, either.
I wonder why nobody of vmscan folks write actual performance improvement value in patch description.
I think this patch point to right direction.
but, unfortunately, this implementation isn't fast as I mesured as.
Quoted 66 lines
The level where it starts serializing is chosen pretty arbitrarily. Suggestions welcome :)
Hannes
---
Prevent over-reclaiming by serializing direct reclaimers below a certain priority level.
Over-reclaiming happens when the sum of the reclaim targets of all reclaiming processes is larger than the sum of the needed free pages, thus leading to excessive eviction of more cache and anonymous pages than required.
A scan iteration over all zones can not be aborted intermittently when enough pages are reclaimed because that would mess up the scan balance between the zones. Instead, prevent that too many processes simultaneously commit themselves to lower priority level scans in the first place.
Chances are that after the exclusive reclaimer has finished, enough memory has been freed that succeeding scanners don't need to drop to lower priority levels at all anymore.
Signed-off-by Johannes Weiner <[email protected]>--- mm/vmscan.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)mm/vmscan.c +7
-0@@ -35,6 +35,7 @@#include <linux/notifier.h> #include <linux/rwsem.h> #include <linux/delay.h> +#include <linux/wait.h> #include <linux/kthread.h> #include <linux/freezer.h> #include <linux/memcontrol.h> @@ -42,6 +43,7 @@#include <linux/sysctl.h> #include <asm/tlbflush.h> +#include <asm/atomic.h> #include <asm/div64.h> #include <linux/swapops.h> @@ -1546,10 +1548,15 @@ static unsigned long shrink_zones(int pr* returns: 0, if no pages reclaimed * else, the number of pages reclaimed */ + +static DECLARE_WAIT_QUEUE_HEAD (reclaim_wait); +static atomic_t reclaim_exclusive =ATOMIC_INIT (0 ); +static unsigned long do_try_to_free_pages (struct zonelist *zonelist,struct scan_control *sc) {int priority; +int exclusive =0 ;unsigned long ret =0 ;unsigned long total_scanned =0 ;unsigned long nr_reclaimed =0 ;
mm/vmscan.c static unsigned long do_try_to_free_page · line 1593
Quoted 7 lines
mm/vmscan.c +4
-0@@ -1580,6 +1587,14 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); +/* +* Serialize aggressive reclaimers +*/ +if (priority <=DEF_PRIORITY /2 && !exclusive) {
On large machine, DEF_PRIORITY / 2 is really catastrophe situation. 2^6 = 64.
if zone has 64GB memory, it mean 1GB reclaim.
I think more early restriction is better.
mm/vmscan.c static unsigned long do_try_to_free_page · line 1597
Quoted 4 lines
mm/vmscan.c +4
-0+wait_event (reclaim_wait, + !atomic_cmpxchg (&reclaim_exclusive,0 ,1 )); + exclusive =1 ; + }
if you want to restrict to one task, you can use mutex.
and this wait_queue should put on global variable. it should be zone variable.
In addision, you don't consider recursive relaim and several task can't sleep there.
please believe me. I have richest experience about reclaim throttling in the planet.
--
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>
Johannes Weiner
maintainerRe: [rfc] vmscan: serialize aggressive reclaimers
Quoted 16 lines · KOSAKI Motohiro
Quoted 16 lines
Since we have to pull through a reclaim cycle once we commited to it, what do you think about serializing the lower priority levels completely?
The idea is that when one reclaimer has done a low priority level iteration with a huge reclaim target, chances are that succeeding reclaimers don't even need to drop to lower levels at all because enough memory has already been freed.
My testprogram maps and faults in a file that is about as large as my physical memory. Then it spawns off n processes that try allocate 1/2n of total memory in anon pages, i.e. half of it in sum. After it ran, I check how much memory has been reclaimed. But my zone sizes are too small to induce enormous reclaim targets so I don't see vast over-reclaims.
Quoted 7 lines
Quoted 4 lines
I have measured the time of other tests on an SMP machine with 4 cores and the following patch applied. I couldn't see any performance degradation. But since the bug is not triggerable here, I can not prove it helps the original problem, either.
I wonder why nobody of vmscan folks write actual performance improvement value in patch description.
That's why I made it RFC. I haven't seriously tested it, I just wanted to know what people that understand more than I do think of the idea.
Quoted 2 lines
I think this patch point to right direction.
but, unfortunately, this implementation isn't fast as I mesured as.
Fair enough.
Quoted 69 lines
Quoted 69 lines
The level where it starts serializing is chosen pretty arbitrarily. Suggestions welcome :)
Hannes
---
Prevent over-reclaiming by serializing direct reclaimers below a certain priority level.
Over-reclaiming happens when the sum of the reclaim targets of all reclaiming processes is larger than the sum of the needed free pages, thus leading to excessive eviction of more cache and anonymous pages than required.
A scan iteration over all zones can not be aborted intermittently when enough pages are reclaimed because that would mess up the scan balance between the zones. Instead, prevent that too many processes simultaneously commit themselves to lower priority level scans in the first place.
Chances are that after the exclusive reclaimer has finished, enough memory has been freed that succeeding scanners don't need to drop to lower priority levels at all anymore.
Signed-off-by Johannes Weiner <[email protected]>--- mm/vmscan.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)mm/vmscan.c +8
-0@@ -35,6 +35,7 @@#include <linux/notifier.h> #include <linux/rwsem.h> #include <linux/delay.h> +#include <linux/wait.h> #include <linux/kthread.h> #include <linux/freezer.h> #include <linux/memcontrol.h> @@ -42,6 +43,7 @@#include <linux/sysctl.h> #include <asm/tlbflush.h> +#include <asm/atomic.h> #include <asm/div64.h> #include <linux/swapops.h> @@ -1546,10 +1548,15 @@ static unsigned long shrink_zones(int pr* returns: 0, if no pages reclaimed * else, the number of pages reclaimed */ + +static DECLARE_WAIT_QUEUE_HEAD (reclaim_wait); +static atomic_t reclaim_exclusive =ATOMIC_INIT (0 ); +static unsigned long do_try_to_free_pages (struct zonelist *zonelist,struct scan_control *sc) {int priority; +int exclusive =0 ;unsigned long ret =0 ;unsigned long total_scanned =0 ;unsigned long nr_reclaimed =0 ;@@ -1580,6 +1587,14 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); +/*
Quoted 8 lines
mm/vmscan.c static unsigned long do_try_to_free_page · line 1593
Quoted 3 lines
mm/vmscan.c +3
-0+* Serialize aggressive reclaimers +*/ +if (priority <=DEF_PRIORITY /2 && !exclusive) {On large machine,
DEF_PRIORITY/ 2 is really catastrophe situation. 2^6 = 64.
if zone has 64GB memory, it mean 1GB reclaim.
I think more early restriction is better.
I am just afraid that it kills parallelity.
Quoted 7 lines
mm/vmscan.c static unsigned long do_try_to_free_page · line 1597
Quoted 4 lines
mm/vmscan.c +4
-0+wait_event (reclaim_wait, + !atomic_cmpxchg (&reclaim_exclusive,0 ,1 )); + exclusive =1 ; + }if you want to restrict to one task, you can use mutex.
and thiswait_queueshould put on global variable. it should be zone variable.
Hm, global or per-zone? Rik suggested to do it per-node and I like that idea.
Quoted 4 lines
In addision, you don't consider recursive relaim and several task can't sleep there.
please believe me. I have richest experience about reclaim throttling in the planet.
Hehe, okay. Than I am glad you don't hate the idea completely. Do you have any patches flying around that do something similar?
Hannes
--
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>