summaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorDavid Rientjes <rientjes@google.com>2018-04-05 19:25:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-06 00:36:27 -0400
commit5ecd9d403ad081ed2de7b118c1e96124d4e0ba6c (patch)
treed830e17c2cd45583a5c0bd593586145fdc6d6796 /mm/page_alloc.c
parent3eda69c92d4751977baf2d34e88a29d4b6affa7d (diff)
mm, page_alloc: wakeup kcompactd even if kswapd cannot free more memory
Kswapd will not wakeup if per-zone watermarks are not failing or if too many previous attempts at background reclaim have failed. This can be true if there is a lot of free memory available. For high- order allocations, kswapd is responsible for waking up kcompactd for background compaction. If the zone is not below its watermarks or reclaim has recently failed (lots of free memory, nothing left to reclaim), kcompactd does not get woken up. When __GFP_DIRECT_RECLAIM is not allowed, allow kcompactd to still be woken up even if kswapd will not reclaim. This allows high-order allocations, such as thp, to still trigger background compaction even when the zone has an abundance of free memory. Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1803111659420.209721@chino.kir.corp.google.com Signed-off-by: David Rientjes <rientjes@google.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Mel Gorman <mgorman@techsingularity.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f6005b7c3446..02c1a60d7937 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3805,16 +3805,18 @@ retry:
3805 return page; 3805 return page;
3806} 3806}
3807 3807
3808static void wake_all_kswapds(unsigned int order, const struct alloc_context *ac) 3808static void wake_all_kswapds(unsigned int order, gfp_t gfp_mask,
3809 const struct alloc_context *ac)
3809{ 3810{
3810 struct zoneref *z; 3811 struct zoneref *z;
3811 struct zone *zone; 3812 struct zone *zone;
3812 pg_data_t *last_pgdat = NULL; 3813 pg_data_t *last_pgdat = NULL;
3814 enum zone_type high_zoneidx = ac->high_zoneidx;
3813 3815
3814 for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, 3816 for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, high_zoneidx,
3815 ac->high_zoneidx, ac->nodemask) { 3817 ac->nodemask) {
3816 if (last_pgdat != zone->zone_pgdat) 3818 if (last_pgdat != zone->zone_pgdat)
3817 wakeup_kswapd(zone, order, ac->high_zoneidx); 3819 wakeup_kswapd(zone, gfp_mask, order, high_zoneidx);
3818 last_pgdat = zone->zone_pgdat; 3820 last_pgdat = zone->zone_pgdat;
3819 } 3821 }
3820} 3822}
@@ -4093,7 +4095,7 @@ retry_cpuset:
4093 goto nopage; 4095 goto nopage;
4094 4096
4095 if (gfp_mask & __GFP_KSWAPD_RECLAIM) 4097 if (gfp_mask & __GFP_KSWAPD_RECLAIM)
4096 wake_all_kswapds(order, ac); 4098 wake_all_kswapds(order, gfp_mask, ac);
4097 4099
4098 /* 4100 /*
4099 * The adjusted alloc_flags might result in immediate success, so try 4101 * The adjusted alloc_flags might result in immediate success, so try
@@ -4151,7 +4153,7 @@ retry_cpuset:
4151retry: 4153retry:
4152 /* Ensure kswapd doesn't accidentally go to sleep as long as we loop */ 4154 /* Ensure kswapd doesn't accidentally go to sleep as long as we loop */
4153 if (gfp_mask & __GFP_KSWAPD_RECLAIM) 4155 if (gfp_mask & __GFP_KSWAPD_RECLAIM)
4154 wake_all_kswapds(order, ac); 4156 wake_all_kswapds(order, gfp_mask, ac);
4155 4157
4156 reserve_flags = __gfp_pfmemalloc_flags(gfp_mask); 4158 reserve_flags = __gfp_pfmemalloc_flags(gfp_mask);
4157 if (reserve_flags) 4159 if (reserve_flags)