From 7f2ee35e2d0317ae2daeca0b4a5fcc885a35b136 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Wed, 20 Feb 2013 13:14:04 +1100 Subject: [PATCH] memcg,vmscan: do not break out targeted reclaim without reclaimed pages Targeted (hard resp. soft) reclaim has traditionally tried to scan one group with decreasing priority until nr_to_reclaim (SWAP_CLUSTER_MAX pages) is reclaimed or all priorities are exhausted. The reclaim is then retried until the limit is met. This approach, however, doesn't work well with deeper hierarchies where groups higher in the hierarchy do not have any or only very few pages (this usually happens if those groups do not have any tasks and they have only re-parented pages after some of their children is removed). Those groups are reclaimed with decreasing priority pointlessly as there is nothing to reclaim from them. An easiest fix is to break out of the memcg iteration loop in shrink_zone only if the whole hierarchy has been visited or sufficient pages have been reclaimed. This is also more natural because the reclaimer expects that the hierarchy under the given root is reclaimed. As a result we can simplify the soft limit reclaim which does its own iteration. Signed-off-by: Michal Hocko Reported-by: Ying Han Cc: KAMEZAWA Hiroyuki Cc: Johannes Weiner Cc: Tejun Heo Cc: Glauber Costa Cc: Li Zefan Signed-off-by: Andrew Morton --- mm/vmscan.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 292f50a2a685..ff869d2db8cd 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1973,18 +1973,17 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc) shrink_lruvec(lruvec, sc); /* - * Limit reclaim has historically picked one - * memcg and scanned it with decreasing - * priority levels until nr_to_reclaim had - * been reclaimed. This priority cycle is - * thus over after a single memcg. - * - * Direct reclaim and kswapd, on the other - * hand, have to scan all memory cgroups to - * fulfill the overall scan target for the + * Direct reclaim and kswapd have to scan all memory + * cgroups to fulfill the overall scan target for the * zone. + * + * Limit reclaim, on the other hand, only cares about + * nr_to_reclaim pages to be reclaimed and it will + * retry with decreasing priority if one round over the + * whole hierarchy is not sufficient. */ - if (!global_reclaim(sc)) { + if (!global_reclaim(sc) && + sc->nr_to_reclaim >= sc->nr_reclaimed) { mem_cgroup_iter_break(root, memcg); break; } -- 2.39.5