vmscan: cut down on struct scan_control
Subsystems (6)
Johannes Weiner
maintainercover vmscan: cut down on struct scan_control
Hi,
here are 5 patches that remove 4 members from struct scan_control.
sc->may_unmap is no longer used after patch #1, sc->may_swap is folded into sc->swappiness, sc->all_unreclaimable is made a return value, and sc->isolate_pages is replaced with a branch on sc->mem_cgroup (reusing a nearby branch, so no additional one) and direct function calling.
So nothing too spectecular. It saves a bit of code and 2 to 4 stack words depending on the wordsize and call path.
Hannes
include/linux/memcontrol.h | 13 +++-- include/linux/swap.h | 4 - mm/memcontrol.c | 13 +++-- mm/vmscan.c | 105 ++++++++++++++++++--------------------------- 4 files changed, 61 insertions(+), 74 deletions(-)
--
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
maintainerPATCH 1/5 vmscan: fix unmapping behaviour for RECLAIM_SWAP
The RECLAIM_SWAP flag in zone_reclaim_mode controls whether zone_reclaim() is allowed to swap or not (obviously).
This is currently implemented by allowing or forbidding reclaim to unmap pages, which also controls reclaim of shared pages and is thus not appropriate.
We can do better by using the sc->may_swap parameter instead, which controls whether the anon lists are scanned.
Unmapping of pages is then allowed per default from zone_reclaim().
--- mm/vmscan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/vmscan.c +2 -2
@@ -2563,8 +2563,8 @@ static int __zone_reclaim(struct zone *zint priority;struct scan_control sc = { .may_writepage = !!(zone_reclaim_mode &RECLAIM_WRITE ), - .may_unmap = !!(zone_reclaim_mode &RECLAIM_SWAP ), - .may_swap =1 , + .may_unmap =1 , + .may_swap = !!(zone_reclaim_mode &RECLAIM_SWAP ), .nr_to_reclaim = max_t(unsigned long, nr_pages,SWAP_CLUSTER_MAX ), .gfp_mask = gfp_mask,
--
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 1/5] vmscan: fix unmapping behaviour for RECLAIM_SWAP
sorry for the long delayed review.
Quoted 20 lines
The
RECLAIM_SWAPflag inzone_reclaim_modecontrols whetherzone_reclaim()is allowed to swap or not (obviously).This is currently implemented by allowing or forbidding reclaim to unmap pages, which also controls reclaim of shared pages and is thus not appropriate.
We can do better by using the
sc->may_swapparameter instead, which controls whether the anon lists are scanned.Unmapping of pages is then allowed per default from
zone_reclaim().Signed-off-by Johannes Weiner <[email protected]>--- mm/vmscan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/vmscan.c static int __zone_reclaim(struct zone *z · line 2570
Quoted 10 lines
mm/vmscan.c +2
-2@@ -2563,8 +2563,8 @@ static int __zone_reclaim(struct zone *zint priority;struct scan_control sc = { .may_writepage = !!(zone_reclaim_mode &RECLAIM_WRITE ), - .may_unmap = !!(zone_reclaim_mode &RECLAIM_SWAP ), - .may_swap =1 , + .may_unmap =1 , + .may_swap = !!(zone_reclaim_mode &RECLAIM_SWAP ), .nr_to_reclaim = max_t(unsigned long, nr_pages,SWAP_CLUSTER_MAX ), .gfp_mask = gfp_mask,
About half years ago, I did post exactly same patch. but at that time, it got Mel's objection. after some discution we agreed to merge documentation change instead code fix.
So, now the documentation describe clearly 4th bit meant no unmap. Please drop this, instead please make s/RECLAIM_SWAP/RECLAIM_MAPPED/ patch.
But if mel ack this, I have no objection.
----------------------------------------------------------
commit 90afa5de6f3fa89a733861e843377302479fcf7e
Author: Mel Gorman <[email protected]> Date: Tue Jun 16 15:33:20 2009 -0700
Documentation/sysctl/vm.txt +8 -5
@@ -315,10 +315,14 @@ min_unmapped_ratio: This is available only on NUMA kernels. -A percentage of the total pages in each zone. Zone reclaim will only -occur if more than this percentage of pages are file backed and unmapped. -This is to insure that a minimal amount of local pages is still available for -file I/O even if the node is overallocated. +This is a percentage of the total pages in each zone. Zone reclaim will +only occur if more than this percentage of pages are in a state that +zone_reclaim_mode allows to be reclaimed. + +If zone_reclaim_mode has the value 4 OR'd, then the percentage is compared +against all file-backed unmapped pages including swapcache pages and tmpfs +files. Otherwise, only unmapped pages backed by normal files but not tmpfs +files and similar are considered. --
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: [patch 1/5] vmscan: fix unmapping behaviour for RECLAIM_SWAP
Hi,
Quoted 1 line · KOSAKI Motohiro
sorry for the long delayed review.
Yeah, I'm a bit on the slow side as well these days. No problem.
Quoted 26 lines
Quoted 26 lines
The
RECLAIM_SWAPflag inzone_reclaim_modecontrols whetherzone_reclaim()is allowed to swap or not (obviously).This is currently implemented by allowing or forbidding reclaim to unmap pages, which also controls reclaim of shared pages and is thus not appropriate.
We can do better by using the
sc->may_swapparameter instead, which controls whether the anon lists are scanned.Unmapping of pages is then allowed per default from
zone_reclaim().Signed-off-by Johannes Weiner <[email protected]>--- mm/vmscan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)mm/vmscan.c +1
-2@@ -2563,8 +2563,8 @@ static int __zone_reclaim(struct zone *zint priority;struct scan_control sc = { .may_writepage = !!(zone_reclaim_mode &RECLAIM_WRITE ), - .may_unmap = !!(zone_reclaim_mode &RECLAIM_SWAP ), - .may_swap =1 , + .may_unmap =1 ,
Quoted 8 lines
mm/vmscan.c static int __zone_reclaim(struct zone *z · line 2570
Quoted 4 lines
mm/vmscan.c +1
-0+ .may_swap = !!(zone_reclaim_mode & RECLAIM_SWAP), .nr_to_reclaim = max_t(unsigned long, nr_pages, SWAP_CLUSTER_MAX), .gfp_mask = gfp_mask,About half years ago, I did post exactly same patch. but at that time, it got Mel's objection. after some discution we agreed to merge documentation change instead code fix.
Interesting, let me dig through the archives.
Quoted 2 lines
So, now the documentation describe clearly 4th bit meant no unmap. Please drop this, instead please make s/RECLAIM_SWAP/RECLAIM_MAPPED/ patch.
Yep.
Thanks,
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>
Johannes Weiner
maintainerPATCH 2/5 vmscan: remove may_unmap scan control
In reply to Johannes WeinerEvery reclaim entry function sets this to the same value.
Make it default behaviour and remove the knob.
--- mm/vmscan.c | 12 ------------ 1 file changed, 12 deletions(-)
mm/vmscan.c +0 -12
@@ -65,9 +65,6 @@ struct scan_control {int may_writepage; -/* Can mapped pages be reclaimed? */ -int may_unmap; -/* Can pages be swapped as part of reclaim? */ int may_swap;
@@ -655,9 +652,6 @@ static unsigned long shrink_page_list(stif (unlikely (!page_evictable (page,NULL ))) goto cull_mlocked; -if (!sc->may_unmap &&page_mapped (page)) - goto keep_locked; -/* Double the slab pressure for mapped and swapcache pages */ if (page_mapped (page) ||PageSwapCache (page)) sc->nr_scanned++;
@@ -1868,7 +1862,6 @@ unsigned long try_to_free_pages(struct z .gfp_mask = gfp_mask, .may_writepage = !laptop_mode, .nr_to_reclaim = SWAP_CLUSTER_MAX, - .may_unmap = 1, .may_swap = 1, .swappiness = vm_swappiness, .order = order,
@@ -1889,7 +1882,6 @@ unsigned long mem_cgroup_shrink_node_zon {struct scan_control sc = { .may_writepage = !laptop_mode, - .may_unmap =1 , .may_swap = !noswap, .swappiness = swappiness, .order =0 ,
@@ -1922,7 +1914,6 @@ unsigned long try_to_free_mem_cgroup_pagstruct zonelist *zonelist;struct scan_control sc = { .may_writepage = !laptop_mode, - .may_unmap =1 , .may_swap = !noswap, .nr_to_reclaim =SWAP_CLUSTER_MAX , .swappiness = swappiness,
@@ -1996,7 +1987,6 @@ static unsigned long balance_pgdat(pg_dastruct reclaim_state *reclaim_state = current->reclaim_state;struct scan_control sc = { .gfp_mask =GFP_KERNEL , - .may_unmap =1 , .may_swap =1 ,/* * kswapd doesn't want to be bailed out while reclaim. because
@@ -2379,7 +2369,6 @@ unsigned long shrink_all_memory(unsignedstruct scan_control sc = { .gfp_mask =GFP_HIGHUSER_MOVABLE , .may_swap =1 , - .may_unmap =1 , .may_writepage =1 , .nr_to_reclaim = nr_to_reclaim, .hibernation_mode =1 ,
@@ -2563,7 +2552,6 @@ static int __zone_reclaim(struct zone *zint priority;struct scan_control sc = { .may_writepage = !!(zone_reclaim_mode &RECLAIM_WRITE ), - .may_unmap =1 , .may_swap = !!(zone_reclaim_mode &RECLAIM_SWAP ), .nr_to_reclaim = max_t(unsigned long, nr_pages,SWAP_CLUSTER_MAX ),
--
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
maintainerPATCH 3/5 vmscan: remove all_unreclaimable scan control
In reply to Johannes WeinerThis scan control is abused to communicate a return value from shrink_zones(). Write this idiomatically and remove the knob.
--- mm/vmscan.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
mm/vmscan.c +6 -8
@@ -70,8 +70,6 @@ struct scan_control {int swappiness; -int all_unreclaimable; -int order;int lumpy_reclaim;
@@ -1701,14 +1699,14 @@ static void shrink_zone(int priority, st* If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static void shrink_zones (int priority,struct zonelist *zonelist, +static int shrink_zones (int priority,struct zonelist *zonelist,struct scan_control *sc) {enum zone_type high_zoneidx =gfp_zone (sc->gfp_mask);struct zoneref *z;struct zone *zone; +int progress =0 ; - sc->all_unreclaimable =1 ;for_each_zone_zonelist_nodemask (zone, z, zonelist, high_zoneidx, sc->nodemask) {if (!populated_zone (zone))
@@ -1724,19 +1722,19 @@ static void shrink_zones(int priority, sif (zone->all_unreclaimable && priority !=DEF_PRIORITY )continue ;/* Let kswapd poll it */ - sc->all_unreclaimable =0 ; }else {/* * Ignore cpuset limitation here. We just want to reduce * # of used pages by us regardless of memory shortage. */ - sc->all_unreclaimable =0 ;mem_cgroup_note_reclaim_priority (sc->mem_cgroup, priority); }shrink_zone (priority, zone, sc); + progress =1 ; } +return progress; }/*
@@ -1789,7 +1787,7 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); -shrink_zones (priority, zonelist, sc); + ret =shrink_zones (priority, zonelist, sc);/* * Don't shrink slabs when reclaiming memory from * over limit cgroups
@@ -1826,7 +1824,7 @@ static unsigned long do_try_to_free_pagecongestion_wait (BLK_RW_ASYNC ,HZ /10 ); }/* top priority shrink_zones still had more to do? don't OOM, then */ -if (!sc->all_unreclaimable &&scanning_global_lru (sc)) +if (ret &&scanning_global_lru (sc)) ret = sc->nr_reclaimed; out:/*
--
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 3/5] vmscan: remove all_unreclaimable scan control
mm/vmscan.c static unsigned long do_try_to_free_page · line 1790
Quoted 6 lines
mm/vmscan.c +1
-1@@ -1789,7 +1787,7 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); -shrink_zones (priority, zonelist, sc); + ret =shrink_zones (priority, zonelist, sc);
Please use more good name instead 'ret' ;)
otherwise looks good.
--
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: [patch 3/5] vmscan: remove all_unreclaimable scan control
Quoted 8 lines · KOSAKI Motohiro
mm/vmscan.c static unsigned long do_try_to_free_page · line 1790
Quoted 6 lines
mm/vmscan.c +1
-1@@ -1789,7 +1787,7 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); -shrink_zones (priority, zonelist, sc); + ret =shrink_zones (priority, zonelist, sc);Please use more good name instead 'ret' ;)
Guess you are right, let me send a follow-up.
Quoted 2 lines
otherwise looks good.
Reviewed-by KOSAKI Motohiro <[email protected]>
Thank you.
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>
Re: [patch 3/5] vmscan: remove all_unreclaimable scan control
In reply to Johannes WeinerQuoted 68 lines · Johannes Weiner
This scan control is abused to communicate a return value from
shrink_zones(). Write this idiomatically and remove the knob.Signed-off-by Johannes Weiner <[email protected]>--- mm/vmscan.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)mm/vmscan.c +5
-7@@ -70,8 +70,6 @@ struct scan_control {int swappiness; -int all_unreclaimable; -int order;int lumpy_reclaim;@@ -1701,14 +1699,14 @@ static void shrink_zone(int priority, st* If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static void shrink_zones (int priority,struct zonelist *zonelist, +static int shrink_zones (int priority,struct zonelist *zonelist,struct scan_control *sc) {enum zone_type high_zoneidx =gfp_zone (sc->gfp_mask);struct zoneref *z;struct zone *zone; +int progress =0 ; - sc->all_unreclaimable =1 ;for_each_zone_zonelist_nodemask (zone, z, zonelist, high_zoneidx, sc->nodemask) {if (!populated_zone (zone))@@ -1724,19 +1722,19 @@ static void shrink_zones(int priority, sif (zone->all_unreclaimable && priority !=DEF_PRIORITY )continue ;/* Let kswapd poll it */ - sc->all_unreclaimable =0 ; }else {/* * Ignore cpuset limitation here. We just want to reduce * # of used pages by us regardless of memory shortage. */ - sc->all_unreclaimable =0 ;mem_cgroup_note_reclaim_priority (sc->mem_cgroup, priority); }shrink_zone (priority, zone, sc); + progress =1 ; } +return progress; }/* @@ -1789,7 +1787,7 @@ static unsigned long do_try_to_free_page sc->nr_scanned =0 ;if (!priority)disable_swap_token (); -shrink_zones (priority, zonelist, sc); + ret =shrink_zones (priority, zonelist, sc);/* * Don't shrink slabs when reclaiming memory from * over limit cgroups
mm/vmscan.c static unsigned long do_try_to_free_page · line 1830
Quoted 8 lines
mm/vmscan.c +1
-1@@ -1826,7 +1824,7 @@ static unsigned long do_try_to_free_pagecongestion_wait (BLK_RW_ASYNC ,HZ /10 ); }/* top priority shrink_zones still had more to do? don't OOM, then */ -if (!sc->all_unreclaimable &&scanning_global_lru (sc)) +if (ret &&scanning_global_lru (sc)) ret = sc->nr_reclaimed; out:/*
I agree with the direction of this patch, but I am seeing a hang when testing with mmotm-2010-05-21-16-05. The following test hangs, unless I remove this patch from mmotm:
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_empty
I think the hang is caused by the following portion of mem_cgroup_force_empty():
while (nr_retries && mem->res.usage > 0) {
int progress;
if (signal_pending(current)) {
ret = -EINTR;
goto out;
}
progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL,
false, get_swappiness(mem));
if (!progress) {
nr_retries--;
/* maybe some writeback is necessary */
congestion_wait(BLK_RW_ASYNC, HZ/10);
}
}With this patch applied, it is possible that when do_try_to_free_pages() calls shrink_zones() for priority 0 that shrink_zones() may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation, scanning_global_lru() is false and the following portion of do_try_to_free_pages() fails to set ret=0.
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;
This leaves ret=1 indicating that do_try_to_free_pages() reclaimed 1 page even though it did not reclaim any pages. Therefore mem_cgroup_force_empty() erroneously believes that try_to_free_mem_cgroup_pages() is making progress (one page at a time), so there is an endless loop.
If I apply the following fix, then your patch does not hang and the system appears to operate correctly.
mm/vmscan.c +0 -0
@@ -1850,7 +1850,7 @@ static unsigned long do_try_to_free_pages(struct
zonelist *zonelist,
congestion_wait(BLK_RW_ASYNC, HZ/10);
}
/* top priority shrink_zones still had more to do? don't OOM,
then */
- if (ret && scanning_global_lru(sc))
+ if (ret)
ret = sc->nr_reclaimed;
out:
/*I have not done thorough testing, so this may introduce other problems. Is there a reason not return nr_reclaimed when operating on a cgroup? This may affect mem_cgroup_hierarchical_reclaim().
--
Greg
--
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: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
CC to memcg folks.
Quoted 34 lines
I agree with the direction of this patch, but I am seeing a hang when testing with mmotm-2010-05-21-16-05. The following test hangs, unless I remove this patch from mmotm:
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyI think the hang is caused by the following portion of
mem_cgroup_force_empty():while (nr_retries && mem->res.usage > 0) { int progress; if (signal_pending(current)) { ret = -EINTR; goto out; } progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL, false, get_swappiness(mem)); if (!progress) { nr_retries--; /* maybe some writeback is necessary */ congestion_wait(BLK_RW_ASYNC, HZ/10); } }With this patch applied, it is possible that when
do_try_to_free_pages()callsshrink_zones()for priority 0 thatshrink_zones()may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation,scanning_global_lru()is false and the following portion ofdo_try_to_free_pages()fails to set ret=0.
Quoted 7 lines
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;This leaves ret=1 indicating that
do_try_to_free_pages()reclaimed 1 page even though it did not reclaim any pages. Thereforemem_cgroup_force_empty()erroneously believes thattry_to_free_mem_cgroup_pages()is making progress (one page at a time), so there is an endless loop.
Good catch!
Yeah, your analysis is fine. thank you for both your testing and making analysis.
Unfortunatelly, this logic need more fix. because It have already been corrupted by another regression. my point is, if priority==0 reclaim failure occur, "ret = sc->nr_reclaimed" makes no sense at all.
The fixing patch is here. What do you think?
From 49a395b21fe1b2f864112e71d027ffcafbdc9fc0 Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <[email protected]>
Date: Tue, 1 Jun 2010 11:29:50 +0900
Subject: [PATCH] vmscan: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
Greg Thelen reported recent Johannes's stack diet patch makes kernel hang. His test is following.
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_empty
Actually, This OOM hard to try logic have been corrupted since following two years old patch.
commit a41f24ea9fd6169b147c53c2392e2887cc1d9247 Author: Nishanth Aravamudan <[email protected]> Date: Tue Apr 29 00:58:25 2008 -0700 page allocator: smarter retry of costly-order allocations
Original intention was "return success if the system have shrinkable zones though priority==0 reclaim was failure". But the above patch changed to "return nr_reclaimed if .....". Oh, That forgot nr_reclaimed may be 0 if priority==0 reclaim failure.
And Johannes's patch made more corrupt. Originally, priority==0 recliam failure on memcg return 0, but this patch changed to return 1. It totally confused memcg.
This patch fixes it completely.
--- mm/vmscan.c | 29 ++++++++++++++++------------- 1 files changed, 16 insertions(+), 13 deletions(-)
mm/vmscan.c +16 -13
@@ -1724,13 +1724,13 @@ static void shrink_zone(int priority, struct zone *zone,* If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static int shrink_zones (int priority,struct zonelist *zonelist, +static bool shrink_zones (int priority,struct zonelist *zonelist,struct scan_control *sc) {enum zone_type high_zoneidx =gfp_zone (sc->gfp_mask);struct zoneref *z;struct zone *zone; -int progress =0 ; +bool all_unreclaimable = true;for_each_zone_zonelist_nodemask (zone, z, zonelist, high_zoneidx, sc->nodemask) {
@@ -1757,9 +1757,9 @@ static int shrink_zones(int priority, struct zonelist *zonelist, }shrink_zone (priority, zone, sc); - progress =1 ; + all_unreclaimable = false; } -return progress; +return all_unreclaimable; }/*
@@ -1782,7 +1782,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, struct scan_control *sc) {int priority; -unsigned long ret =0 ; +bool all_unreclaimable;unsigned long total_scanned =0 ;struct reclaim_state *reclaim_state = current->reclaim_state;unsigned long lru_pages =0 ;
@@ -1813,7 +1813,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, sc->nr_scanned =0 ;if (!priority)disable_swap_token (); - ret =shrink_zones (priority, zonelist, sc); + all_unreclaimable =shrink_zones (priority, zonelist, sc);/* * Don't shrink slabs when reclaiming memory from * over limit cgroups
@@ -1826,10 +1826,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, } } total_scanned += sc->nr_scanned; -if (sc->nr_reclaimed >= sc->nr_to_reclaim) { - ret = sc->nr_reclaimed; +if (sc->nr_reclaimed >= sc->nr_to_reclaim) goto out; - }/* * Try to write back as many pages as we just scanned. This
@@ -1849,9 +1847,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, priority < DEF_PRIORITY - 2)congestion_wait (BLK_RW_ASYNC ,HZ /10 ); } -/* top priority shrink_zones still had more to do? don't OOM, then */ -if (ret &&scanning_global_lru (sc)) - ret = sc->nr_reclaimed; + out:/* * Now that we've scanned all the zones at this priority level, note
@@ -1877,7 +1873,14 @@ out:delayacct_freepages_end ();put_mems_allowed (); -return ret; +if (sc->nr_reclaimed) +return sc->nr_reclaimed; + +/* top priority shrink_zones still had more to do? don't OOM, then */ +if (scanning_global_lru (sc) && !all_unreclaimable) +return 1 ; + +return 0 ; } unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
Signature · 10 lines
1.6.5.2 -- 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: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
Quoted 59 lines · On Tue, 1 Jun 2010 12:29:41 +0900 (JST) KOSAKI Motohiro…
Quoted 5 lines
With this patch applied, it is possible that when
do_try_to_free_pages()callsshrink_zones()for priority 0 thatshrink_zones()may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation,scanning_global_lru()is false and the following portion ofdo_try_to_free_pages()fails to set ret=0.Quoted 7 lines
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;This leaves ret=1 indicating that
do_try_to_free_pages()reclaimed 1 page even though it did not reclaim any pages. Thereforemem_cgroup_force_empty()erroneously believes thattry_to_free_mem_cgroup_pages()is making progress (one page at a time), so there is an endless loop.Good catch!
Yeah, your analysis is fine. thank you for both your testing and making analysis.
Unfortunatelly, this logic need more fix. because It have already been corrupted by another regression. my point is, if priority==0 reclaim failure occur, "ret =
sc->nr_reclaimed" makes no sense at all.The fixing patch is here. What do you think?
From
49a395b21fe1b2f864112e71d027ffcafbdc9fc0Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <[email protected]>
Date: Tue, 1 Jun 2010 11:29:50 +0900
Subject: [PATCH] vmscan: Fixdo_try_to_free_pages()return value when priority==0 reclaim failureGreg Thelen reported recent Johannes's stack diet patch makes kernel hang. His test is following.
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyActually, This OOM hard to try logic have been corrupted since following two years old patch.
commit a41f24ea9fd6169b147c53c2392e2887cc1d9247 Author: Nishanth Aravamudan <[email protected]> Date: Tue Apr 29 00:58:25 2008 -0700 page allocator: smarter retry of costly-order allocationsOriginal intention was "return success if the system have shrinkable zones though priority==0 reclaim was failure". But the above patch changed to "return
nr_reclaimedif .....". Oh, That forgotnr_reclaimedmay be 0 if priority==0 reclaim failure.And Johannes's patch made more corrupt. Originally, priority==0 recliam failure on memcg return 0, but this patch changed to return 1. It totally confused memcg.
Quoted 5 lines
This patch fixes it completely.
Reported-by Greg Thelen <[email protected]>Signed-off-by KOSAKI Motohiro <[email protected]>Cc Johannes Weiner <[email protected]>
Thank you very much!!
--
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: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
In reply to KOSAKI MotohiroQuoted 86 lines · KOSAKI Motohiro
CC to memcg folks.
Quoted 34 lines
I agree with the direction of this patch, but I am seeing a hang when testing with mmotm-2010-05-21-16-05. The following test hangs, unless I remove this patch from mmotm:
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyI think the hang is caused by the following portion of
mem_cgroup_force_empty():while (nr_retries && mem->res.usage > 0) { int progress; if (signal_pending(current)) { ret = -EINTR; goto out; } progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL, false, get_swappiness(mem)); if (!progress) { nr_retries--; /* maybe some writeback is necessary */ congestion_wait(BLK_RW_ASYNC, HZ/10); } }With this patch applied, it is possible that when
do_try_to_free_pages()callsshrink_zones()for priority 0 thatshrink_zones()may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation,scanning_global_lru()is false and the following portion ofdo_try_to_free_pages()fails to set ret=0.Quoted 7 lines
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;This leaves ret=1 indicating that
do_try_to_free_pages()reclaimed 1 page even though it did not reclaim any pages. Thereforemem_cgroup_force_empty()erroneously believes thattry_to_free_mem_cgroup_pages()is making progress (one page at a time), so there is an endless loop.Good catch!
Yeah, your analysis is fine. thank you for both your testing and making analysis.
Unfortunatelly, this logic need more fix. because It have already been corrupted by another regression. my point is, if priority==0 reclaim failure occur, "ret =
sc->nr_reclaimed" makes no sense at all.The fixing patch is here. What do you think?
From
49a395b21fe1b2f864112e71d027ffcafbdc9fc0Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <[email protected]>
Date: Tue, 1 Jun 2010 11:29:50 +0900
Subject: [PATCH] vmscan: Fixdo_try_to_free_pages()return value when priority==0 reclaim failureGreg Thelen reported recent Johannes's stack diet patch makes kernel hang. His test is following.
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyActually, This OOM hard to try logic have been corrupted since following two years old patch.
commit a41f24ea9fd6169b147c53c2392e2887cc1d9247 Author: Nishanth Aravamudan <[email protected]> Date: Tue Apr 29 00:58:25 2008 -0700 page allocator: smarter retry of costly-order allocationsOriginal intention was "return success if the system have shrinkable zones though priority==0 reclaim was failure". But the above patch changed to "return
nr_reclaimedif .....". Oh, That forgotnr_reclaimedmay be 0 if priority==0 reclaim failure.
Quoted 6 lines
And Johannes's patch made more corrupt. Originally, priority==0 recliam failure on memcg return 0, but this patch changed to return 1. It totally confused memcg.
This patch fixes it completely.
The patch seems reasonable to me, although I've not tested it
Signature · 8 lines
Three Cheers, Balbir -- 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: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
Quoted 92 lines · On Tue, 1 Jun 2010 13:40:59 +0530 Balbir Singh <[email protected]>…
Quoted 90 lines · KOSAKI Motohiro
CC to memcg folks.
Quoted 34 lines
I agree with the direction of this patch, but I am seeing a hang when testing with mmotm-2010-05-21-16-05. The following test hangs, unless I remove this patch from mmotm:
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyI think the hang is caused by the following portion of
mem_cgroup_force_empty():while (nr_retries && mem->res.usage > 0) { int progress; if (signal_pending(current)) { ret = -EINTR; goto out; } progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL, false, get_swappiness(mem)); if (!progress) { nr_retries--; /* maybe some writeback is necessary */ congestion_wait(BLK_RW_ASYNC, HZ/10); } }With this patch applied, it is possible that when
do_try_to_free_pages()callsshrink_zones()for priority 0 thatshrink_zones()may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation,scanning_global_lru()is false and the following portion ofdo_try_to_free_pages()fails to set ret=0.Quoted 7 lines
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;This leaves ret=1 indicating that
do_try_to_free_pages()reclaimed 1 page even though it did not reclaim any pages. Thereforemem_cgroup_force_empty()erroneously believes thattry_to_free_mem_cgroup_pages()is making progress (one page at a time), so there is an endless loop.Good catch!
Yeah, your analysis is fine. thank you for both your testing and making analysis.
Unfortunatelly, this logic need more fix. because It have already been corrupted by another regression. my point is, if priority==0 reclaim failure occur, "ret =
sc->nr_reclaimed" makes no sense at all.The fixing patch is here. What do you think?
From
49a395b21fe1b2f864112e71d027ffcafbdc9fc0Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <[email protected]>
Date: Tue, 1 Jun 2010 11:29:50 +0900
Subject: [PATCH] vmscan: Fixdo_try_to_free_pages()return value when priority==0 reclaim failureGreg Thelen reported recent Johannes's stack diet patch makes kernel hang. His test is following.
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyActually, This OOM hard to try logic have been corrupted since following two years old patch.
commit a41f24ea9fd6169b147c53c2392e2887cc1d9247 Author: Nishanth Aravamudan <[email protected]> Date: Tue Apr 29 00:58:25 2008 -0700 page allocator: smarter retry of costly-order allocationsOriginal intention was "return success if the system have shrinkable zones though priority==0 reclaim was failure". But the above patch changed to "return
nr_reclaimedif .....". Oh, That forgotnr_reclaimedmay be 0 if priority==0 reclaim failure.And Johannes's patch made more corrupt. Originally, priority==0 recliam failure on memcg return 0, but this patch changed to return 1. It totally confused memcg.
Quoted 7 lines
Quoted 2 lines
This patch fixes it completely.
The patch seems reasonable to me, although I've not tested it
Acked-by Balbir Singh <[email protected]>
Don't worry, I tested.
Thanks,
-Kame
--
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: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
In reply to KOSAKI MotohiroQuoted 46 lines · KOSAKI Motohiro
CC to memcg folks.
Quoted 34 lines
I agree with the direction of this patch, but I am seeing a hang when testing with mmotm-2010-05-21-16-05. The following test hangs, unless I remove this patch from mmotm:
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyI think the hang is caused by the following portion of
mem_cgroup_force_empty():while (nr_retries && mem->res.usage > 0) { int progress; if (signal_pending(current)) { ret = -EINTR; goto out; } progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL, false, get_swappiness(mem)); if (!progress) { nr_retries--; /* maybe some writeback is necessary */ congestion_wait(BLK_RW_ASYNC, HZ/10); } }With this patch applied, it is possible that when
do_try_to_free_pages()callsshrink_zones()for priority 0 thatshrink_zones()may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation,scanning_global_lru()is false and the following portion ofdo_try_to_free_pages()fails to set ret=0.Quoted 7 lines
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;This leaves ret=1 indicating that
do_try_to_free_pages()reclaimed 1 page even though it did not reclaim any pages. Thereforemem_cgroup_force_empty()erroneously believes thattry_to_free_mem_cgroup_pages()is making progress (one page at a time), so there is an endless loop.Good catch!
Quoted 8 lines
Yeah, your analysis is fine. thank you for both your testing and making analysis.
Unfortunatelly, this logic need more fix. because It have already been corrupted by another regression. my point is, if priority==0 reclaim failure occur, "ret =
sc->nr_reclaimed" makes no sense at all.The fixing patch is here. What do you think?
Your fixing patch looks good and passes the test which detected the issue. Thank you.
Quoted 133 lines
From
49a395b21fe1b2f864112e71d027ffcafbdc9fc0Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <[email protected]>
Date: Tue, 1 Jun 2010 11:29:50 +0900
Subject: [PATCH] vmscan: Fixdo_try_to_free_pages()return value when priority==0 reclaim failureGreg Thelen reported recent Johannes's stack diet patch makes kernel hang. His test is following.
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyActually, This OOM hard to try logic have been corrupted since following two years old patch.
commit a41f24ea9fd6169b147c53c2392e2887cc1d9247 Author: Nishanth Aravamudan <[email protected]> Date: Tue Apr 29 00:58:25 2008 -0700 page allocator: smarter retry of costly-order allocationsOriginal intention was "return success if the system have shrinkable zones though priority==0 reclaim was failure". But the above patch changed to "return
nr_reclaimedif .....". Oh, That forgotnr_reclaimedmay be 0 if priority==0 reclaim failure.And Johannes's patch made more corrupt. Originally, priority==0 recliam failure on memcg return 0, but this patch changed to return 1. It totally confused memcg.
This patch fixes it completely.
Reported-by Greg Thelen <[email protected]>Signed-off-by KOSAKI Motohiro <[email protected]>Cc Johannes Weiner <[email protected]>--- mm/vmscan.c | 29 ++++++++++++++++------------- 1 files changed, 16 insertions(+), 13 deletions(-)mm/vmscan.c +16
-13@@ -1724,13 +1724,13 @@ static void shrink_zone(int priority, struct zone *zone,* If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static int shrink_zones (int priority,struct zonelist *zonelist, +static bool shrink_zones (int priority,struct zonelist *zonelist,struct scan_control *sc) {enum zone_type high_zoneidx =gfp_zone (sc->gfp_mask);struct zoneref *z;struct zone *zone; -int progress =0 ; +bool all_unreclaimable = true;for_each_zone_zonelist_nodemask (zone, z, zonelist, high_zoneidx, sc->nodemask) {@@ -1757,9 +1757,9 @@ static int shrink_zones(int priority, struct zonelist *zonelist, }shrink_zone (priority, zone, sc); - progress =1 ; + all_unreclaimable = false; } -return progress; +return all_unreclaimable; }/* @@ -1782,7 +1782,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, struct scan_control *sc) {int priority; -unsigned long ret =0 ; +bool all_unreclaimable;unsigned long total_scanned =0 ;struct reclaim_state *reclaim_state = current->reclaim_state;unsigned long lru_pages =0 ;@@ -1813,7 +1813,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, sc->nr_scanned =0 ;if (!priority)disable_swap_token (); - ret =shrink_zones (priority, zonelist, sc); + all_unreclaimable =shrink_zones (priority, zonelist, sc);/* * Don't shrink slabs when reclaiming memory from * over limit cgroups @@ -1826,10 +1826,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, } } total_scanned += sc->nr_scanned; -if (sc->nr_reclaimed >= sc->nr_to_reclaim) { - ret = sc->nr_reclaimed; +if (sc->nr_reclaimed >= sc->nr_to_reclaim) goto out; - }/* * Try to write back as many pages as we just scanned. This @@ -1849,9 +1847,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, priority < DEF_PRIORITY - 2)congestion_wait (BLK_RW_ASYNC ,HZ /10 ); } -/* top priority shrink_zones still had more to do? don't OOM, then */ -if (ret &&scanning_global_lru (sc)) - ret = sc->nr_reclaimed; + out:/* * Now that we've scanned all the zones at this priority level, note @@ -1877,7 +1873,14 @@ out:delayacct_freepages_end ();put_mems_allowed (); -return ret; +if (sc->nr_reclaimed) +return sc->nr_reclaimed; + +/* top priority shrink_zones still had more to do? don't OOM, then */ +if (scanning_global_lru (sc) && !all_unreclaimable) +return 1 ; + +return 0 ; } unsigned long try_to_free_pages(struct zonelist *zonelist, int order,Signature · 1 line
1.6.5.2
--
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: Fix do_try_to_free_pages() return value when priority==0 reclaim failure
In reply to KOSAKI MotohiroQuoted 90 lines · KOSAKI Motohiro
CC to memcg folks.
Quoted 34 lines
I agree with the direction of this patch, but I am seeing a hang when testing with mmotm-2010-05-21-16-05. The following test hangs, unless I remove this patch from mmotm:
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyI think the hang is caused by the following portion of
mem_cgroup_force_empty():while (nr_retries && mem->res.usage > 0) { int progress; if (signal_pending(current)) { ret = -EINTR; goto out; } progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL, false, get_swappiness(mem)); if (!progress) { nr_retries--; /* maybe some writeback is necessary */ congestion_wait(BLK_RW_ASYNC, HZ/10); } }With this patch applied, it is possible that when
do_try_to_free_pages()callsshrink_zones()for priority 0 thatshrink_zones()may return 1 indicating progress, even though no pages may have been reclaimed. Because this is a cgroup operation,scanning_global_lru()is false and the following portion ofdo_try_to_free_pages()fails to set ret=0.Quoted 7 lines
Quoted 2 lines
if (ret && scanning_global_lru(sc))ret =
sc->nr_reclaimed;This leaves ret=1 indicating that
do_try_to_free_pages()reclaimed 1 page even though it did not reclaim any pages. Thereforemem_cgroup_force_empty()erroneously believes thattry_to_free_mem_cgroup_pages()is making progress (one page at a time), so there is an endless loop.Good catch!
Yeah, your analysis is fine. thank you for both your testing and making analysis.
Unfortunatelly, this logic need more fix. because It have already been corrupted by another regression. my point is, if priority==0 reclaim failure occur, "ret =
sc->nr_reclaimed" makes no sense at all.The fixing patch is here. What do you think?
From
49a395b21fe1b2f864112e71d027ffcafbdc9fc0Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <[email protected]>
Date: Tue, 1 Jun 2010 11:29:50 +0900
Subject: [PATCH] vmscan: Fixdo_try_to_free_pages()return value when priority==0 reclaim failureGreg Thelen reported recent Johannes's stack diet patch makes kernel hang. His test is following.
mount -t cgroup none /cgroups -o memory
mkdir /cgroups/cg1
echo $$ > /cgroups/cg1/tasks
dd bs=1024 count=1024 if=/dev/null of=/data/foo
echo $$ > /cgroups/tasks
echo 1 > /cgroups/cg1/memory.force_emptyActually, This OOM hard to try logic have been corrupted since following two years old patch.
commit a41f24ea9fd6169b147c53c2392e2887cc1d9247 Author: Nishanth Aravamudan <[email protected]> Date: Tue Apr 29 00:58:25 2008 -0700 page allocator: smarter retry of costly-order allocationsOriginal intention was "return success if the system have shrinkable zones though priority==0 reclaim was failure". But the above patch changed to "return
nr_reclaimedif .....". Oh, That forgotnr_reclaimedmay be 0 if priority==0 reclaim failure.And Johannes's patch made more corrupt. Originally, priority==0 recliam failure on memcg return 0, but this patch changed to return 1. It totally confused memcg.
Quoted 5 lines
This patch fixes it completely.
Reported-by Greg Thelen <[email protected]>Signed-off-by KOSAKI Motohiro <[email protected]>Cc Johannes Weiner <[email protected]>
Greg, thanks for this great bug report. KOSAKI-san, thanks a lot for fixing it. And I am sorry I did not reply earlier, there is just too much going on right now :/
--
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
maintainerPATCH 4/5 vmscan: remove isolate_pages callback scan control
In reply to Johannes WeinerFor now, we have global isolation vs. memory control group isolation, do not allow the reclaim entry function to set an arbitrary page isolation callback, we do not need that flexibility.
And since we already pass around the group descriptor for the memory control group isolation case, just use it to decide which one of the two isolator functions to use.
The decisions can be merged into nearby branches, so no extra cost there. In fact, we save the indirect calls.
--- include/linux/memcontrol.h | 13 ++++++----- mm/vmscan.c | 52 ++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 30 deletions(-)
mm/vmscan.c +28 -24
@@ -82,12 +82,6 @@ struct scan_control {* are scanned. */ nodemask_t *nodemask; - -/* Pluggable isolate pages callback */ -unsigned long (*isolate_pages)(unsigned long nr,struct list_head *dst, -unsigned long *scanned,int order,int mode, -struct zone *z,struct mem_cgroup *mem_cont, -int active,int file); };#define lru_to_page (_head) (list_entry((_head)->prev, struct page, lru))
@@ -1000,7 +994,6 @@ static unsigned long isolate_pages_globastruct list_head *dst, unsigned long *scanned, int order, int mode, struct zone *z, - struct mem_cgroup *mem_cont, int active, int file) { int lru = LRU_BASE;
@@ -1144,11 +1137,11 @@ static unsigned long shrink_inactive_lisunsigned long nr_anon;unsigned long nr_file; - nr_taken = sc->isolate_pages (SWAP_CLUSTER_MAX , - &page_list, &nr_scan, sc->order, mode, - zone, sc->mem_cgroup,0 , file); -if (scanning_global_lru (sc)) { + nr_taken =isolate_pages_global (SWAP_CLUSTER_MAX , + &page_list, &nr_scan, + sc->order, mode, + zone,0 , file); zone->pages_scanned += nr_scan;if (current_is_kswapd ()) __count_zone_vm_events(PGSCAN_KSWAPD, zone,
@@ -1156,6 +1149,16 @@ static unsigned long shrink_inactive_liselse __count_zone_vm_events (PGSCAN_DIRECT , zone, nr_scan); + }else { + nr_taken =mem_cgroup_isolate_pages (SWAP_CLUSTER_MAX , + &page_list, &nr_scan, + sc->order, mode, + zone, sc->mem_cgroup, +0 , file); +/* +* mem_cgroup_isolate_pages() keeps track of +* scanned pages on its own. +*/ }if (nr_taken ==0 )
@@ -1333,16 +1336,23 @@ static void shrink_active_list(unsignedlru_add_drain ();spin_lock_irq (&zone->lru_lock); - nr_taken = sc->isolate_pages (nr_pages, &l_hold, &pgscanned, sc->order, -ISOLATE_ACTIVE , zone, - sc->mem_cgroup,1 , file); -/* -* zone->pages_scanned is used for detect zone's oom -* mem_cgroup remembers nr_scan by itself. -*/ if (scanning_global_lru (sc)) { + nr_taken =isolate_pages_global (nr_pages, &l_hold, + &pgscanned, sc->order, +ISOLATE_ACTIVE , zone, +1 , file); zone->pages_scanned += pgscanned; + }else { + nr_taken =mem_cgroup_isolate_pages (nr_pages, &l_hold, + &pgscanned, sc->order, +ISOLATE_ACTIVE , zone, + sc->mem_cgroup,1 , file); +/* +* mem_cgroup_isolate_pages() keeps track of +* scanned pages on its own. +*/ } + reclaim_stat->recent_scanned[file] += nr_taken;__count_zone_vm_events (PGREFILL , zone, pgscanned);
@@ -1864,7 +1874,6 @@ unsigned long try_to_free_pages(struct z .swappiness = vm_swappiness, .order = order, .mem_cgroup = NULL, - .isolate_pages = isolate_pages_global, .nodemask = nodemask, };
@@ -1884,7 +1893,6 @@ unsigned long mem_cgroup_shrink_node_zon .swappiness = swappiness, .order = 0, .mem_cgroup = mem, - .isolate_pages = mem_cgroup_isolate_pages, };nodemask_t nm =nodemask_of_node (nid);
@@ -1917,7 +1925,6 @@ unsigned long try_to_free_mem_cgroup_pag .swappiness = swappiness, .order = 0, .mem_cgroup = mem_cont, - .isolate_pages = mem_cgroup_isolate_pages, .nodemask = NULL, /* we don't care the placement */ };
@@ -1994,7 +2001,6 @@ static unsigned long balance_pgdat(pg_da .swappiness = vm_swappiness, .order = order, .mem_cgroup = NULL, - .isolate_pages = isolate_pages_global, };/* * temp_priority is used to remember the scanning priority at which
@@ -2372,7 +2378,6 @@ unsigned long shrink_all_memory(unsigned .hibernation_mode = 1, .swappiness = vm_swappiness, .order = 0, - .isolate_pages = isolate_pages_global, };struct zonelist * zonelist =node_zonelist (numa_node_id (), sc.gfp_mask);struct task_struct *p = current;
@@ -2556,7 +2561,6 @@ static int __zone_reclaim(struct zone *z .gfp_mask = gfp_mask, .swappiness = vm_swappiness, .order = order, - .isolate_pages = isolate_pages_global, };unsigned long slab_reclaimable;
include/linux/memcontrol.h +7 -6
@@ -25,6 +25,13 @@ struct page_cgroup;struct page ;struct mm_struct ; +extern unsigned long mem_cgroup_isolate_pages (unsigned long nr_to_scan, +struct list_head *dst, +unsigned long *scanned,int order, +int mode,struct zone *z, +struct mem_cgroup *mem_cont, +int active,int file); +#ifdef CONFIG_CGROUP_MEM_RES_CTLR /* * All "charge" functions with gfp_mask should use GFP_KERNEL or
@@ -64,12 +71,6 @@ extern void mem_cgroup_uncharge_cache_paextern int mem_cgroup_shmem_charge_fallback (struct page *page,struct mm_struct *mm,gfp_t gfp_mask); -extern unsigned long mem_cgroup_isolate_pages (unsigned long nr_to_scan, -struct list_head *dst, -unsigned long *scanned,int order, -int mode,struct zone *z, -struct mem_cgroup *mem_cont, -int active,int file);extern void mem_cgroup_out_of_memory (struct mem_cgroup *mem,gfp_t gfp_mask);int task_in_mem_cgroup (struct task_struct *task,const struct mem_cgroup *mem);
--
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 4/5] vmscan: remove isolate_pages callback scan control
Quoted 61 lines
For now, we have global isolation vs. memory control group isolation, do not allow the reclaim entry function to set an arbitrary page isolation callback, we do not need that flexibility.
And since we already pass around the group descriptor for the memory control group isolation case, just use it to decide which one of the two isolator functions to use.
The decisions can be merged into nearby branches, so no extra cost there. In fact, we save the indirect calls.
Signed-off-by Johannes Weiner <[email protected]>--- include/linux/memcontrol.h | 13 ++++++----- mm/vmscan.c | 52 ++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 30 deletions(-)mm/vmscan.c +5
-11@@ -82,12 +82,6 @@ struct scan_control {* are scanned. */ nodemask_t *nodemask; - -/* Pluggable isolate pages callback */ -unsigned long (*isolate_pages)(unsigned long nr,struct list_head *dst, -unsigned long *scanned,int order,int mode, -struct zone *z,struct mem_cgroup *mem_cont, -int active,int file); };#define lru_to_page (_head) (list_entry((_head)->prev, struct page, lru))@@ -1000,7 +994,6 @@ static unsigned long isolate_pages_globastruct list_head *dst, unsigned long *scanned, int order, int mode, struct zone *z, - struct mem_cgroup *mem_cont, int active, int file) { int lru = LRU_BASE;@@ -1144,11 +1137,11 @@ static unsigned long shrink_inactive_lisunsigned long nr_anon;unsigned long nr_file; - nr_taken = sc->isolate_pages (SWAP_CLUSTER_MAX , - &page_list, &nr_scan, sc->order, mode, - zone, sc->mem_cgroup,0 , file); -if (scanning_global_lru (sc)) { + nr_taken =isolate_pages_global (SWAP_CLUSTER_MAX , + &page_list, &nr_scan, + sc->order, mode, + zone,0 , file); zone->pages_scanned += nr_scan;if (current_is_kswapd ()) __count_zone_vm_events(PGSCAN_KSWAPD, zone,@@ -1156,6 +1149,16 @@ static unsigned long shrink_inactive_liselse __count_zone_vm_events (PGSCAN_DIRECT , zone, nr_scan); + }else {
mm/vmscan.c static unsigned long shrink_inactive_lis · line 1162
Quoted 10 lines
mm/vmscan.c +9
-0+ nr_taken =mem_cgroup_isolate_pages (SWAP_CLUSTER_MAX , + &page_list, &nr_scan, + sc->order, mode, + zone, sc->mem_cgroup, +0 , file); +/* +* mem_cgroup_isolate_pages() keeps track of +* scanned pages on its own. +*/ }
There are the same logic in shrink_active/inactive_list. Can we make wrapper function? It probably improve code readability.
--
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: [patch 4/5] vmscan: remove isolate_pages callback scan control
Quoted 66 lines · KOSAKI Motohiro
Quoted 66 lines
For now, we have global isolation vs. memory control group isolation, do not allow the reclaim entry function to set an arbitrary page isolation callback, we do not need that flexibility.
And since we already pass around the group descriptor for the memory control group isolation case, just use it to decide which one of the two isolator functions to use.
The decisions can be merged into nearby branches, so no extra cost there. In fact, we save the indirect calls.
Signed-off-by Johannes Weiner <[email protected]>--- include/linux/memcontrol.h | 13 ++++++----- mm/vmscan.c | 52 ++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 30 deletions(-)mm/vmscan.c +10
-11@@ -82,12 +82,6 @@ struct scan_control {* are scanned. */ nodemask_t *nodemask; - -/* Pluggable isolate pages callback */ -unsigned long (*isolate_pages)(unsigned long nr,struct list_head *dst, -unsigned long *scanned,int order,int mode, -struct zone *z,struct mem_cgroup *mem_cont, -int active,int file); };#define lru_to_page (_head) (list_entry((_head)->prev, struct page, lru))@@ -1000,7 +994,6 @@ static unsigned long isolate_pages_globastruct list_head *dst, unsigned long *scanned, int order, int mode, struct zone *z, - struct mem_cgroup *mem_cont, int active, int file) { int lru = LRU_BASE;@@ -1144,11 +1137,11 @@ static unsigned long shrink_inactive_lisunsigned long nr_anon;unsigned long nr_file; - nr_taken = sc->isolate_pages (SWAP_CLUSTER_MAX , - &page_list, &nr_scan, sc->order, mode, - zone, sc->mem_cgroup,0 , file); -if (scanning_global_lru (sc)) { + nr_taken =isolate_pages_global (SWAP_CLUSTER_MAX , + &page_list, &nr_scan, + sc->order, mode, + zone,0 , file); zone->pages_scanned += nr_scan;if (current_is_kswapd ()) __count_zone_vm_events(PGSCAN_KSWAPD, zone,@@ -1156,6 +1149,16 @@ static unsigned long shrink_inactive_liselse __count_zone_vm_events (PGSCAN_DIRECT , zone, nr_scan); + }else { + nr_taken =mem_cgroup_isolate_pages (SWAP_CLUSTER_MAX , + &page_list, &nr_scan, + sc->order, mode, + zone, sc->mem_cgroup, +0 , file);
Quoted 8 lines
mm/vmscan.c static unsigned long shrink_inactive_lis · line 1162
Quoted 5 lines
mm/vmscan.c +4
-0+/* +* mem_cgroup_isolate_pages() keeps track of +* scanned pages on its own. +*/ }There are the same logic in shrink_active/inactive_list. Can we make wrapper function? It probably improve code readability.
They are not completely identical, PGSCAN_DIRECT/PGSCAN_KSWAPD accounting is only done in shrink_inactive_list(), so we would need an extra branch. Can we leave it like that for now?
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>
Re: [patch 4/5] vmscan: remove isolate_pages callback scan control
Quoted 6 lines
Quoted 2 lines
There are the same logic in shrink_active/inactive_list. Can we make wrapper function? It probably improve code readability.
They are not completely identical, PGSCAN_DIRECT/PGSCAN_KSWAPD accounting is only done in
shrink_inactive_list(), so we would need an extra branch. Can we leave it like that for now?
Ah. ok, I see.
--
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
maintainerPATCH 5/5 vmscan: remove may_swap scan control
In reply to Johannes WeinerThe may_swap scan control flag can be naturally merged into the swappiness parameter: swap only if swappiness is non-zero.
--- include/linux/swap.h | 4 ++-- mm/memcontrol.c | 13 +++++++++---- mm/vmscan.c | 27 +++++++++------------------ 3 files changed, 20 insertions(+), 24 deletions(-)
include/linux/swap.h +2 -2
@@ -248,10 +248,10 @@ static inline void lru_cache_add_active_extern unsigned long try_to_free_pages (struct zonelist *zonelist,int order,gfp_t gfp_mask,nodemask_t *mask);extern unsigned long try_to_free_mem_cgroup_pages (struct mem_cgroup *mem, -gfp_t gfp_mask,bool noswap, +gfp_t gfp_mask,unsigned int swappiness);extern unsigned long mem_cgroup_shrink_node_zone (struct mem_cgroup *mem, -gfp_t gfp_mask,bool noswap, +gfp_t gfp_mask,unsigned int swappiness,struct zone *zone,int nid);
mm/memcontrol.c +9 -4
@@ -1234,6 +1234,8 @@ static int mem_cgroup_hierarchical_recla noswap = true;while (1 ) { +unsigned int swappiness; + victim =mem_cgroup_select_victim (root_mem);if (victim == root_mem) { loop++;
@@ -1268,13 +1270,16 @@ static int mem_cgroup_hierarchical_reclacontinue ; }/* we use swappiness of local cgroup */ +if (noswap) + swappiness =0 ; +else + swappiness =get_swappiness (victim);if (check_soft) ret =mem_cgroup_shrink_node_zone (victim, gfp_mask, - noswap,get_swappiness (victim), zone, - zone->zone_pgdat->node_id); + swappiness, zone, zone->zone_pgdat->node_id);else ret =try_to_free_mem_cgroup_pages (victim, gfp_mask, - noswap,get_swappiness (victim)); + swappiness);css_put (&victim->css);/* * At shrinking usage, we can't check we should stop here or
@@ -2966,7 +2971,7 @@ try_to_free: goto out; } progress =try_to_free_mem_cgroup_pages (mem,GFP_KERNEL , - false,get_swappiness (mem)); +get_swappiness (mem));if (!progress) { nr_retries--;/* maybe some writeback is necessary */
mm/vmscan.c +9 -18
@@ -65,9 +65,6 @@ struct scan_control {int may_writepage; -/* Can pages be swapped as part of reclaim? */ -int may_swap; -int swappiness;int order;
@@ -1545,7 +1542,7 @@ static void get_scan_count(struct zone *int noswap =0 ;/* If we have no swap space, do not bother scanning anon pages. */ -if (!sc->may_swap || (nr_swap_pages <=0 )) { +if (!sc->swappiness || (nr_swap_pages <=0 )) { noswap =1 ; fraction[0 ] =0 ; fraction[1 ] =1 ;
@@ -1870,7 +1867,6 @@ unsigned long try_to_free_pages(struct z .gfp_mask = gfp_mask, .may_writepage = !laptop_mode, .nr_to_reclaim = SWAP_CLUSTER_MAX, - .may_swap = 1, .swappiness = vm_swappiness, .order = order, .mem_cgroup = NULL,
@@ -1883,13 +1879,11 @@ unsigned long try_to_free_pages(struct z #ifdef CONFIG_CGROUP_MEM_RES_CTLR unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, - gfp_t gfp_mask, bool noswap, - unsigned int swappiness, - struct zone *zone, int nid) + gfp_t gfp_mask, unsigned int swappiness, + struct zone *zone, int nid) { struct scan_control sc = { .may_writepage = !laptop_mode, - .may_swap = !noswap, .swappiness = swappiness, .order = 0, .mem_cgroup = mem,
@@ -1913,14 +1907,11 @@ unsigned long mem_cgroup_shrink_node_zon }unsigned long try_to_free_mem_cgroup_pages (struct mem_cgroup *mem_cont, -gfp_t gfp_mask, -bool noswap, -unsigned int swappiness) +gfp_t gfp_mask,unsigned int swappiness) {struct zonelist *zonelist;struct scan_control sc = { .may_writepage = !laptop_mode, - .may_swap = !noswap, .nr_to_reclaim =SWAP_CLUSTER_MAX , .swappiness = swappiness, .order =0 ,
@@ -1992,7 +1983,6 @@ static unsigned long balance_pgdat(pg_dastruct reclaim_state *reclaim_state = current->reclaim_state;struct scan_control sc = { .gfp_mask =GFP_KERNEL , - .may_swap =1 ,/* * kswapd doesn't want to be bailed out while reclaim. because * we want to put equal scanning pressure on each zone.
@@ -2372,7 +2362,6 @@ unsigned long shrink_all_memory(unsignedstruct reclaim_state reclaim_state;struct scan_control sc = { .gfp_mask =GFP_HIGHUSER_MOVABLE , - .may_swap =1 , .may_writepage =1 , .nr_to_reclaim = nr_to_reclaim, .hibernation_mode =1 ,
@@ -2554,16 +2543,18 @@ static int __zone_reclaim(struct zone *zstruct reclaim_state reclaim_state;int priority;struct scan_control sc = { - .may_writepage = !!(zone_reclaim_mode &RECLAIM_WRITE ), - .may_swap = !!(zone_reclaim_mode &RECLAIM_SWAP ), .nr_to_reclaim = max_t(unsigned long, nr_pages,SWAP_CLUSTER_MAX ), .gfp_mask = gfp_mask, - .swappiness = vm_swappiness, .order = order, };unsigned long slab_reclaimable; +if (zone_reclaim_mode &RECLAIM_WRITE ) + sc.may_writepage =1 ; +if (zone_reclaim_mode &RECLAIM_SWAP ) + sc.swappiness = vm_swappiness; +disable_swap_token ();cond_resched ();/*
--
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 5/5] vmscan: remove may_swap scan control
Quoted 2 lines
The
may_swapscan control flag can be naturally merged into the swappiness parameter: swap only if swappiness is non-zero.
Sorry, NAK.
AFAIK, swappiness==0 is very widely used in MySQL users community. They expect this parameter mean "very prefer to discard file cache rather than swap, but not completely disable swap".
We shouldn't ignore the real world use case. even if it is a bit strange.
--
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: [patch 5/5] vmscan: remove may_swap scan control
Quoted 10 lines · KOSAKI Motohiro
Quoted 2 lines
The
may_swapscan control flag can be naturally merged into the swappiness parameter: swap only if swappiness is non-zero.Sorry, NAK.
AFAIK, swappiness==0 is very widely used in MySQL users community. They expect this parameter mean "very prefer to discard file cache rather than swap, but not completely disable swap".
We shouldn't ignore the real world use case. even if it is a bit strange.
Bummer. It's really ugly to have 'zero' mean 'almost nothing'.
But since swappiness is passed around as an int, I think we can instead use -1 for 'no swap'. Let me look into it and send a follow-up patch for this as well.
Thanks!
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>
Re: [patch 5/5] vmscan: remove may_swap scan control
Quoted 12 lines · KOSAKI Motohiro
Quoted 10 lines
Quoted 2 lines
The
may_swapscan control flag can be naturally merged into the swappiness parameter: swap only if swappiness is non-zero.Sorry, NAK.
AFAIK, swappiness==0 is very widely used in MySQL users community. They expect this parameter mean "very prefer to discard file cache rather than swap, but not completely disable swap".
We shouldn't ignore the real world use case. even if it is a bit strange.
Quoted 7 lines
Bummer. It's really ugly to have 'zero' mean 'almost nothing'.
But since swappiness is passed around as an int, I think we can instead use -1 for 'no swap'. Let me look into it and send a follow-up patch for this as well.
Thanks!
Yup, -1 is perfectly acceptable.
Moreover, I hope such strange habbit will disappear int the future. I think our recent activity help to change their mind. At that time, we can change the code more radically.
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>