Skip to content

Commit f1427a1

Browse files
committed
slab: make percpu sheaves compatible with kmalloc_nolock()/kfree_nolock()
Before we enable percpu sheaves for kmalloc caches, we need to make sure kmalloc_nolock() and kfree_nolock() will continue working properly and not spin when not allowed to. Percpu sheaves themselves use local_trylock() so they are already compatible. We just need to be careful with the barn->lock spin_lock. Pass a new allow_spin parameter where necessary to use spin_trylock_irqsave(). In kmalloc_nolock_noprof() we can now attempt alloc_from_pcs() safely, for now it will always fail until we enable sheaves for kmalloc caches next. Similarly in kfree_nolock() we can attempt free_to_pcs(). Reviewed-by: Suren Baghdasaryan <surenb@google.com> Reviewed-by: Harry Yoo <harry.yoo@oracle.com> Reviewed-by: Hao Li <hao.li@linux.dev> Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
1 parent f3421f8 commit f1427a1

File tree

1 file changed

+60
-22
lines changed

1 file changed

+60
-22
lines changed

mm/slub.c

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2889,15 +2889,19 @@ static void pcs_destroy(struct kmem_cache *s)
28892889
s->cpu_sheaves = NULL;
28902890
}
28912891

2892-
static struct slab_sheaf *barn_get_empty_sheaf(struct node_barn *barn)
2892+
static struct slab_sheaf *barn_get_empty_sheaf(struct node_barn *barn,
2893+
bool allow_spin)
28932894
{
28942895
struct slab_sheaf *empty = NULL;
28952896
unsigned long flags;
28962897

28972898
if (!data_race(barn->nr_empty))
28982899
return NULL;
28992900

2900-
spin_lock_irqsave(&barn->lock, flags);
2901+
if (likely(allow_spin))
2902+
spin_lock_irqsave(&barn->lock, flags);
2903+
else if (!spin_trylock_irqsave(&barn->lock, flags))
2904+
return NULL;
29012905

29022906
if (likely(barn->nr_empty)) {
29032907
empty = list_first_entry(&barn->sheaves_empty,
@@ -2974,15 +2978,19 @@ static struct slab_sheaf *barn_get_full_or_empty_sheaf(struct node_barn *barn)
29742978
* change.
29752979
*/
29762980
static struct slab_sheaf *
2977-
barn_replace_empty_sheaf(struct node_barn *barn, struct slab_sheaf *empty)
2981+
barn_replace_empty_sheaf(struct node_barn *barn, struct slab_sheaf *empty,
2982+
bool allow_spin)
29782983
{
29792984
struct slab_sheaf *full = NULL;
29802985
unsigned long flags;
29812986

29822987
if (!data_race(barn->nr_full))
29832988
return NULL;
29842989

2985-
spin_lock_irqsave(&barn->lock, flags);
2990+
if (likely(allow_spin))
2991+
spin_lock_irqsave(&barn->lock, flags);
2992+
else if (!spin_trylock_irqsave(&barn->lock, flags))
2993+
return NULL;
29862994

29872995
if (likely(barn->nr_full)) {
29882996
full = list_first_entry(&barn->sheaves_full, struct slab_sheaf,
@@ -3003,7 +3011,8 @@ barn_replace_empty_sheaf(struct node_barn *barn, struct slab_sheaf *empty)
30033011
* barn. But if there are too many full sheaves, reject this with -E2BIG.
30043012
*/
30053013
static struct slab_sheaf *
3006-
barn_replace_full_sheaf(struct node_barn *barn, struct slab_sheaf *full)
3014+
barn_replace_full_sheaf(struct node_barn *barn, struct slab_sheaf *full,
3015+
bool allow_spin)
30073016
{
30083017
struct slab_sheaf *empty;
30093018
unsigned long flags;
@@ -3014,7 +3023,10 @@ barn_replace_full_sheaf(struct node_barn *barn, struct slab_sheaf *full)
30143023
if (!data_race(barn->nr_empty))
30153024
return ERR_PTR(-ENOMEM);
30163025

3017-
spin_lock_irqsave(&barn->lock, flags);
3026+
if (likely(allow_spin))
3027+
spin_lock_irqsave(&barn->lock, flags);
3028+
else if (!spin_trylock_irqsave(&barn->lock, flags))
3029+
return ERR_PTR(-EBUSY);
30183030

30193031
if (likely(barn->nr_empty)) {
30203032
empty = list_first_entry(&barn->sheaves_empty, struct slab_sheaf,
@@ -5008,7 +5020,8 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
50085020
return NULL;
50095021
}
50105022

5011-
full = barn_replace_empty_sheaf(barn, pcs->main);
5023+
full = barn_replace_empty_sheaf(barn, pcs->main,
5024+
gfpflags_allow_spinning(gfp));
50125025

50135026
if (full) {
50145027
stat(s, BARN_GET);
@@ -5025,7 +5038,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
50255038
empty = pcs->spare;
50265039
pcs->spare = NULL;
50275040
} else {
5028-
empty = barn_get_empty_sheaf(barn);
5041+
empty = barn_get_empty_sheaf(barn, true);
50295042
}
50305043
}
50315044

@@ -5165,7 +5178,8 @@ void *alloc_from_pcs(struct kmem_cache *s, gfp_t gfp, int node)
51655178
}
51665179

51675180
static __fastpath_inline
5168-
unsigned int alloc_from_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
5181+
unsigned int alloc_from_pcs_bulk(struct kmem_cache *s, gfp_t gfp, size_t size,
5182+
void **p)
51695183
{
51705184
struct slub_percpu_sheaves *pcs;
51715185
struct slab_sheaf *main;
@@ -5199,7 +5213,8 @@ unsigned int alloc_from_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
51995213
return allocated;
52005214
}
52015215

5202-
full = barn_replace_empty_sheaf(barn, pcs->main);
5216+
full = barn_replace_empty_sheaf(barn, pcs->main,
5217+
gfpflags_allow_spinning(gfp));
52035218

52045219
if (full) {
52055220
stat(s, BARN_GET);
@@ -5700,7 +5715,7 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node)
57005715
gfp_t alloc_gfp = __GFP_NOWARN | __GFP_NOMEMALLOC | gfp_flags;
57015716
struct kmem_cache *s;
57025717
bool can_retry = true;
5703-
void *ret = ERR_PTR(-EBUSY);
5718+
void *ret;
57045719

57055720
VM_WARN_ON_ONCE(gfp_flags & ~(__GFP_ACCOUNT | __GFP_ZERO |
57065721
__GFP_NO_OBJ_EXT));
@@ -5731,6 +5746,12 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node)
57315746
*/
57325747
return NULL;
57335748

5749+
ret = alloc_from_pcs(s, alloc_gfp, node);
5750+
if (ret)
5751+
goto success;
5752+
5753+
ret = ERR_PTR(-EBUSY);
5754+
57345755
/*
57355756
* Do not call slab_alloc_node(), since trylock mode isn't
57365757
* compatible with slab_pre_alloc_hook/should_failslab and
@@ -5767,6 +5788,7 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node)
57675788
ret = NULL;
57685789
}
57695790

5791+
success:
57705792
maybe_wipe_obj_freeptr(s, ret);
57715793
slab_post_alloc_hook(s, NULL, alloc_gfp, 1, &ret,
57725794
slab_want_init_on_alloc(alloc_gfp, s), size);
@@ -6087,7 +6109,8 @@ static void __pcs_install_empty_sheaf(struct kmem_cache *s,
60876109
* unlocked.
60886110
*/
60896111
static struct slub_percpu_sheaves *
6090-
__pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs)
6112+
__pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
6113+
bool allow_spin)
60916114
{
60926115
struct slab_sheaf *empty;
60936116
struct node_barn *barn;
@@ -6111,7 +6134,7 @@ __pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs)
61116134
put_fail = false;
61126135

61136136
if (!pcs->spare) {
6114-
empty = barn_get_empty_sheaf(barn);
6137+
empty = barn_get_empty_sheaf(barn, allow_spin);
61156138
if (empty) {
61166139
pcs->spare = pcs->main;
61176140
pcs->main = empty;
@@ -6125,15 +6148,16 @@ __pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs)
61256148
return pcs;
61266149
}
61276150

6128-
empty = barn_replace_full_sheaf(barn, pcs->main);
6151+
empty = barn_replace_full_sheaf(barn, pcs->main, allow_spin);
61296152

61306153
if (!IS_ERR(empty)) {
61316154
stat(s, BARN_PUT);
61326155
pcs->main = empty;
61336156
return pcs;
61346157
}
61356158

6136-
if (PTR_ERR(empty) == -E2BIG) {
6159+
/* sheaf_flush_unused() doesn't support !allow_spin */
6160+
if (PTR_ERR(empty) == -E2BIG && allow_spin) {
61376161
/* Since we got here, spare exists and is full */
61386162
struct slab_sheaf *to_flush = pcs->spare;
61396163

@@ -6158,6 +6182,14 @@ __pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs)
61586182
alloc_empty:
61596183
local_unlock(&s->cpu_sheaves->lock);
61606184

6185+
/*
6186+
* alloc_empty_sheaf() doesn't support !allow_spin and it's
6187+
* easier to fall back to freeing directly without sheaves
6188+
* than add the support (and to sheaf_flush_unused() above)
6189+
*/
6190+
if (!allow_spin)
6191+
return NULL;
6192+
61616193
empty = alloc_empty_sheaf(s, GFP_NOWAIT);
61626194
if (empty)
61636195
goto got_empty;
@@ -6200,7 +6232,7 @@ __pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs)
62006232
* The object is expected to have passed slab_free_hook() already.
62016233
*/
62026234
static __fastpath_inline
6203-
bool free_to_pcs(struct kmem_cache *s, void *object)
6235+
bool free_to_pcs(struct kmem_cache *s, void *object, bool allow_spin)
62046236
{
62056237
struct slub_percpu_sheaves *pcs;
62066238

@@ -6211,7 +6243,7 @@ bool free_to_pcs(struct kmem_cache *s, void *object)
62116243

62126244
if (unlikely(pcs->main->size == s->sheaf_capacity)) {
62136245

6214-
pcs = __pcs_replace_full_main(s, pcs);
6246+
pcs = __pcs_replace_full_main(s, pcs, allow_spin);
62156247
if (unlikely(!pcs))
62166248
return false;
62176249
}
@@ -6336,7 +6368,7 @@ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj)
63366368
goto fail;
63376369
}
63386370

6339-
empty = barn_get_empty_sheaf(barn);
6371+
empty = barn_get_empty_sheaf(barn, true);
63406372

63416373
if (empty) {
63426374
pcs->rcu_free = empty;
@@ -6456,7 +6488,7 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
64566488
goto no_empty;
64576489

64586490
if (!pcs->spare) {
6459-
empty = barn_get_empty_sheaf(barn);
6491+
empty = barn_get_empty_sheaf(barn, true);
64606492
if (!empty)
64616493
goto no_empty;
64626494

@@ -6470,7 +6502,7 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
64706502
goto do_free;
64716503
}
64726504

6473-
empty = barn_replace_full_sheaf(barn, pcs->main);
6505+
empty = barn_replace_full_sheaf(barn, pcs->main, true);
64746506
if (IS_ERR(empty)) {
64756507
stat(s, BARN_PUT_FAIL);
64766508
goto no_empty;
@@ -6722,7 +6754,7 @@ void slab_free(struct kmem_cache *s, struct slab *slab, void *object,
67226754

67236755
if (likely(!IS_ENABLED(CONFIG_NUMA) || slab_nid(slab) == numa_mem_id())
67246756
&& likely(!slab_test_pfmemalloc(slab))) {
6725-
if (likely(free_to_pcs(s, object)))
6757+
if (likely(free_to_pcs(s, object, true)))
67266758
return;
67276759
}
67286760

@@ -6993,6 +7025,12 @@ void kfree_nolock(const void *object)
69937025
* since kasan quarantine takes locks and not supported from NMI.
69947026
*/
69957027
kasan_slab_free(s, x, false, false, /* skip quarantine */true);
7028+
7029+
if (likely(!IS_ENABLED(CONFIG_NUMA) || slab_nid(slab) == numa_mem_id())) {
7030+
if (likely(free_to_pcs(s, x, false)))
7031+
return;
7032+
}
7033+
69967034
do_slab_free(s, slab, x, x, 0, _RET_IP_);
69977035
}
69987036
EXPORT_SYMBOL_GPL(kfree_nolock);
@@ -7545,7 +7583,7 @@ int kmem_cache_alloc_bulk_noprof(struct kmem_cache *s, gfp_t flags, size_t size,
75457583
size--;
75467584
}
75477585

7548-
i = alloc_from_pcs_bulk(s, size, p);
7586+
i = alloc_from_pcs_bulk(s, flags, size, p);
75497587

75507588
if (i < size) {
75517589
/*

0 commit comments

Comments
 (0)