aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@techsingularity.net>2016-07-28 18:46:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-28 19:07:41 -0400
commit84c7a7771fc846cfe98af086f5d5ec6d0ca6249c (patch)
tree3d44f4716fd957aca4d1c41cbad73a0cbc2d45b0 /mm/vmscan.c
parentd9f21d426dc6064ce1c698e947fdde525c3ad8e8 (diff)
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>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1f35364e0feb..b3829c7e3a7d 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3123,7 +3123,6 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
3123 .may_writepage = !laptop_mode, 3123 .may_writepage = !laptop_mode,
3124 .may_unmap = 1, 3124 .may_unmap = 1,
3125 .may_swap = 1, 3125 .may_swap = 1,
3126 .reclaim_idx = classzone_idx,
3127 }; 3126 };
3128 count_vm_event(PAGEOUTRUN); 3127 count_vm_event(PAGEOUTRUN);
3129 3128
@@ -3131,12 +3130,17 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
3131 bool raise_priority = true; 3130 bool raise_priority = true;
3132 3131
3133 sc.nr_reclaimed = 0; 3132 sc.nr_reclaimed = 0;
3133 sc.reclaim_idx = classzone_idx;
3134 3134
3135 /* 3135 /*
3136 * If the number of buffer_heads in the machine exceeds the 3136 * If the number of buffer_heads exceeds the maximum allowed
3137 * maximum allowed level then reclaim from all zones. This is 3137 * then consider reclaiming from all zones. This has a dual
3138 * not specific to highmem as highmem may not exist but it is 3138 * purpose -- on 64-bit systems it is expected that
3139 * it is expected that buffer_heads are stripped in writeback. 3139 * buffer_heads are stripped during active rotation. On 32-bit
3140 * systems, highmem pages can pin lowmem memory and shrinking
3141 * buffers can relieve lowmem pressure. Reclaim may still not
3142 * go ahead if all eligible zones for the original allocation
3143 * request are balanced to avoid excessive reclaim from kswapd.
3140 */ 3144 */
3141 if (buffer_heads_over_limit) { 3145 if (buffer_heads_over_limit) {
3142 for (i = MAX_NR_ZONES - 1; i >= 0; i--) { 3146 for (i = MAX_NR_ZONES - 1; i >= 0; i--) {
@@ -3155,14 +3159,16 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
3155 * Scanning from low to high zone would allow congestion to be 3159 * Scanning from low to high zone would allow congestion to be
3156 * cleared during a very small window when a small low 3160 * cleared during a very small window when a small low
3157 * zone was balanced even under extreme pressure when the 3161 * zone was balanced even under extreme pressure when the
3158 * overall node may be congested. 3162 * overall node may be congested. Note that sc.reclaim_idx
3163 * is not used as buffer_heads_over_limit may have adjusted
3164 * it.
3159 */ 3165 */
3160 for (i = sc.reclaim_idx; i >= 0; i--) { 3166 for (i = classzone_idx; i >= 0; i--) {
3161 zone = pgdat->node_zones + i; 3167 zone = pgdat->node_zones + i;
3162 if (!populated_zone(zone)) 3168 if (!populated_zone(zone))
3163 continue; 3169 continue;
3164 3170
3165 if (zone_balanced(zone, sc.order, sc.reclaim_idx)) 3171 if (zone_balanced(zone, sc.order, classzone_idx))
3166 goto out; 3172 goto out;
3167 } 3173 }
3168 3174