[PATCH] mm/slab: allow sheaf refill if blocking is not allowed

From: Vlastimil Babka (SUSE)

Date: Wed Feb 25 2026 - 03:40:22 EST


Signed-off-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>
---
mm/slub.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 862642c165ed..258307270442 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4526,7 +4526,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
struct slab_sheaf *empty = NULL;
struct slab_sheaf *full;
struct node_barn *barn;
- bool can_alloc;
+ bool allow_spin;

lockdep_assert_held(this_cpu_ptr(&s->cpu_sheaves->lock));

@@ -4547,8 +4547,9 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
return NULL;
}

- full = barn_replace_empty_sheaf(barn, pcs->main,
- gfpflags_allow_spinning(gfp));
+ allow_spin = gfpflags_allow_spinning(gfp);
+
+ full = barn_replace_empty_sheaf(barn, pcs->main, allow_spin);

if (full) {
stat(s, BARN_GET);
@@ -4558,9 +4559,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,

stat(s, BARN_GET_FAIL);

- can_alloc = gfpflags_allow_blocking(gfp);
-
- if (can_alloc) {
+ if (allow_spin) {
if (pcs->spare) {
empty = pcs->spare;
pcs->spare = NULL;
@@ -4571,7 +4570,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,

local_unlock(&s->cpu_sheaves->lock);

- if (!can_alloc)
+ if (!allow_spin)
return NULL;

if (empty) {
@@ -4591,11 +4590,8 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
if (!full)
return NULL;

- /*
- * we can reach here only when gfpflags_allow_blocking
- * so this must not be an irq
- */
- local_lock(&s->cpu_sheaves->lock);
+ if (!local_trylock(&s->cpu_sheaves->lock))
+ goto barn_put;
pcs = this_cpu_ptr(s->cpu_sheaves);

/*
@@ -4626,6 +4622,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
return pcs;
}

+barn_put:
barn_put_full_sheaf(barn, full);
stat(s, BARN_PUT);

--
2.53.0