summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mm/slub.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 11a99bd06ac7..90f0e6667130 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3791,6 +3791,7 @@ static void *get_from_any_partial(struct kmem_cache *s, struct partial_context *
struct zone *zone;
enum zone_type highest_zoneidx = gfp_zone(pc->flags);
unsigned int cpuset_mems_cookie;
+ bool allow_spin = gfpflags_allow_spinning(pc->flags);
/*
* The defrag ratio allows a configuration of the tradeoffs between
@@ -3815,7 +3816,15 @@ static void *get_from_any_partial(struct kmem_cache *s, struct partial_context *
return NULL;
do {
- cpuset_mems_cookie = read_mems_allowed_begin();
+ /*
+ * read_mems_allowed_begin() accesses current->mems_allowed_seq,
+ * a seqcount_spinlock_t that is not NMI-safe. Do not access
+ * current->mems_allowed_seq and avoid retry when GFP flags
+ * indicate spinning is not allowed.
+ */
+ if (allow_spin)
+ cpuset_mems_cookie = read_mems_allowed_begin();
+
zonelist = node_zonelist(mempolicy_slab_node(), pc->flags);
for_each_zone_zonelist(zone, z, zonelist, highest_zoneidx) {
struct kmem_cache_node *n;
@@ -3839,7 +3848,7 @@ static void *get_from_any_partial(struct kmem_cache *s, struct partial_context *
}
}
}
- } while (read_mems_allowed_retry(cpuset_mems_cookie));
+ } while (allow_spin && read_mems_allowed_retry(cpuset_mems_cookie));
#endif /* CONFIG_NUMA */
return NULL;
}