syzbot is reporting circular locking dependency which involves zonelist_update_seq seqlock, for zonelist_update_seq is checked while doing GFP_ATOMIC allocation. Since zonelist_update_seq is checked for avoiding unnecessary OOM kill, there is no need to check zonelist_update_seq for memory allocations which will fail without OOM kill. Therefore, let's keep locking dependency simple, by not checking zonelist_update_seq from !__GFP_DIRECT_RECLAIM allocations. Reported-by: syzbot <syzbot+223c7461c58c58a4cb10@xxxxxxxxxxxxxxxxxxxxxxxxx> Link: https://syzkaller.appspot.com/bug?extid=223c7461c58c58a4cb10 Fixes: 3d36424b3b58 ("mm/page_alloc: fix race condition between build_all_zonelists and page allocation") Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> --- mm/page_alloc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7136c36c5d01..80ef79b23865 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4759,17 +4759,17 @@ EXPORT_SYMBOL_GPL(fs_reclaim_release); */ static DEFINE_SEQLOCK(zonelist_update_seq); -static unsigned int zonelist_iter_begin(void) +static unsigned int zonelist_iter_begin(gfp_t gfp_mask) { - if (IS_ENABLED(CONFIG_MEMORY_HOTREMOVE)) + if (IS_ENABLED(CONFIG_MEMORY_HOTREMOVE) && (gfp_mask & __GFP_DIRECT_RECLAIM)) return read_seqbegin(&zonelist_update_seq); return 0; } -static unsigned int check_retry_zonelist(unsigned int seq) +static unsigned int check_retry_zonelist(unsigned int seq, gfp_t gfp_mask) { - if (IS_ENABLED(CONFIG_MEMORY_HOTREMOVE)) + if (IS_ENABLED(CONFIG_MEMORY_HOTREMOVE) && (gfp_mask & __GFP_DIRECT_RECLAIM)) return read_seqretry(&zonelist_update_seq, seq); return seq; @@ -5083,7 +5083,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, no_progress_loops = 0; compact_priority = DEF_COMPACT_PRIORITY; cpuset_mems_cookie = read_mems_allowed_begin(); - zonelist_iter_cookie = zonelist_iter_begin(); + zonelist_iter_cookie = zonelist_iter_begin(gfp_mask); /* * The fast path uses conservative alloc_flags to succeed only until @@ -5261,7 +5261,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, * a unnecessary OOM kill. */ if (check_retry_cpuset(cpuset_mems_cookie, ac) || - check_retry_zonelist(zonelist_iter_cookie)) + check_retry_zonelist(zonelist_iter_cookie, gfp_mask)) goto restart; /* Reclaim has failed us, start killing things */ @@ -5287,7 +5287,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, * a unnecessary OOM kill. */ if (check_retry_cpuset(cpuset_mems_cookie, ac) || - check_retry_zonelist(zonelist_iter_cookie)) + check_retry_zonelist(zonelist_iter_cookie, gfp_mask)) goto restart; /* -- 2.34.1