Skip to content

Commit fb1091f

Browse files
Vlastimil Babka (SUSE)tehcaster
authored andcommitted
mm/slab: allow sheaf refill if blocking is not allowed
Ming Lei reported [1] a regression in the ublk null target benchmark due to sheaves. The profile shows that the alloc_from_pcs() fastpath fails and allocations fall back to ___slab_alloc(). It also shows the allocations happen through mempool_alloc(). The strategy of mempool_alloc() is to call the underlying allocator (here slab) without __GFP_DIRECT_RECLAIM first. This does not play well with __pcs_replace_empty_main() checking for gfpflags_allow_blocking() to decide if it should refill an empty sheaf or fallback to the slowpath, so we end up falling back. We could change the mempool strategy but there might be other paths doing the same ting. So instead allow sheaf refill when blocking is not allowed, changing the condition to gfpflags_allow_spinning(). The original condition was unnecessarily restrictive. Note this doesn't fully resolve the regression [1] as another component of that are memoryless nodes, which is to be addressed separately. Reported-by: Ming Lei <ming.lei@redhat.com> Fixes: e47c897 ("slab: add sheaves to most caches") Link: https://lore.kernel.org/all/aZ0SbIqaIkwoW2mB@fedora/ [1] Link: https://patch.msgid.link/20260302095536.34062-2-vbabka@kernel.org Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
1 parent 48647d3 commit fb1091f

1 file changed

Lines changed: 10 additions & 12 deletions

File tree

mm/slub.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,7 +4567,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
45674567
struct slab_sheaf *empty = NULL;
45684568
struct slab_sheaf *full;
45694569
struct node_barn *barn;
4570-
bool can_alloc;
4570+
bool allow_spin;
45714571

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

@@ -4588,8 +4588,9 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
45884588
return NULL;
45894589
}
45904590

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

45944595
if (full) {
45954596
stat(s, BARN_GET);
@@ -4599,9 +4600,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
45994600

46004601
stat(s, BARN_GET_FAIL);
46014602

4602-
can_alloc = gfpflags_allow_blocking(gfp);
4603-
4604-
if (can_alloc) {
4603+
if (allow_spin) {
46054604
if (pcs->spare) {
46064605
empty = pcs->spare;
46074606
pcs->spare = NULL;
@@ -4611,8 +4610,9 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
46114610
}
46124611

46134612
local_unlock(&s->cpu_sheaves->lock);
4613+
pcs = NULL;
46144614

4615-
if (!can_alloc)
4615+
if (!allow_spin)
46164616
return NULL;
46174617

46184618
if (empty) {
@@ -4632,11 +4632,8 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
46324632
if (!full)
46334633
return NULL;
46344634

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

46424639
/*
@@ -4667,6 +4664,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
46674664
return pcs;
46684665
}
46694666

4667+
barn_put:
46704668
barn_put_full_sheaf(barn, full);
46714669
stat(s, BARN_PUT);
46724670

0 commit comments

Comments
 (0)