Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm, vmscan: Have kswapd reclaim from all zones if reclaiming and buffer_heads_over_limit

The buffer_heads_over_limit limit in kswapd is inconsistent with direct
reclaim behaviour. It may force an an attempt to reclaim from all zones
and then not reclaim at all because higher zones were balanced than
required by the original request.

This patch will causes kswapd to consider reclaiming from all zones if
buffer_heads_over_limit. However, if there are eligible zones for the
allocation request that woke kswapd then no reclaim will occur even if
buffer_heads_over_limit. This avoids kswapd over-reclaiming just
because buffer_heads_over_limit.

[mgorman@techsingularity.net: fix comment about buffer_heads_over_limit]
Link: http://lkml.kernel.org/r/1468404004-5085-2-git-send-email-mgorman@techsingularity.net
Link: http://lkml.kernel.org/r/1467970510-21195-28-git-send-email-mgorman@techsingularity.net
Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Cc: Hillf Danton <hillf.zj@alibaba-inc.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mel Gorman and committed by
Linus Torvalds
84c7a777 d9f21d42

+14 -8
+14 -8
mm/vmscan.c
··· 3123 3123 .may_writepage = !laptop_mode, 3124 3124 .may_unmap = 1, 3125 3125 .may_swap = 1, 3126 - .reclaim_idx = classzone_idx, 3127 3126 }; 3128 3127 count_vm_event(PAGEOUTRUN); 3129 3128 ··· 3130 3131 bool raise_priority = true; 3131 3132 3132 3133 sc.nr_reclaimed = 0; 3134 + sc.reclaim_idx = classzone_idx; 3133 3135 3134 3136 /* 3135 - * If the number of buffer_heads in the machine exceeds the 3136 - * maximum allowed level then reclaim from all zones. This is 3137 - * not specific to highmem as highmem may not exist but it is 3138 - * it is expected that buffer_heads are stripped in writeback. 3137 + * If the number of buffer_heads exceeds the maximum allowed 3138 + * then consider reclaiming from all zones. This has a dual 3139 + * purpose -- on 64-bit systems it is expected that 3140 + * buffer_heads are stripped during active rotation. On 32-bit 3141 + * systems, highmem pages can pin lowmem memory and shrinking 3142 + * buffers can relieve lowmem pressure. Reclaim may still not 3143 + * go ahead if all eligible zones for the original allocation 3144 + * request are balanced to avoid excessive reclaim from kswapd. 3139 3145 */ 3140 3146 if (buffer_heads_over_limit) { 3141 3147 for (i = MAX_NR_ZONES - 1; i >= 0; i--) { ··· 3159 3155 * Scanning from low to high zone would allow congestion to be 3160 3156 * cleared during a very small window when a small low 3161 3157 * zone was balanced even under extreme pressure when the 3162 - * overall node may be congested. 3158 + * overall node may be congested. Note that sc.reclaim_idx 3159 + * is not used as buffer_heads_over_limit may have adjusted 3160 + * it. 3163 3161 */ 3164 - for (i = sc.reclaim_idx; i >= 0; i--) { 3162 + for (i = classzone_idx; i >= 0; i--) { 3165 3163 zone = pgdat->node_zones + i; 3166 3164 if (!populated_zone(zone)) 3167 3165 continue; 3168 3166 3169 - if (zone_balanced(zone, sc.order, sc.reclaim_idx)) 3167 + if (zone_balanced(zone, sc.order, classzone_idx)) 3170 3168 goto out; 3171 3169 } 3172 3170