[PATCH] mm, page_alloc: fix race with cpuset update or removal

From: Vlastimil Babka
Date: Fri Jan 13 2017 - 04:01:26 EST


Changelog and S-O-B TBD.
---
mm/page_alloc.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 6de9440e3ae2..c397f146843a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3775,9 +3775,17 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
/*
* Restore the original nodemask if it was potentially replaced with
* &cpuset_current_mems_allowed to optimize the fast-path attempt.
+ * Also recalculate the starting point for the zonelist iterator or
+ * we could end up iterating over non-eligible zones endlessly.
*/
- if (cpusets_enabled())
+ if (unlikely(ac.nodemask != nodemask)) {
ac.nodemask = nodemask;
+ ac.preferred_zoneref = first_zones_zonelist(ac.zonelist,
+ ac.high_zoneidx, ac.nodemask);
+ if (!ac.preferred_zoneref)
+ goto no_zone;
+ }
+
page = __alloc_pages_slowpath(alloc_mask, order, &ac);

no_zone:
--
2.11.0