Skip to content

Commit e47c897

Browse files
committed
slab: add sheaves to most caches
In the first step to replace cpu (partial) slabs with sheaves, enable sheaves for almost all caches. Treat args->sheaf_capacity as a minimum, and calculate sheaf capacity with a formula that roughly follows the formula for number of objects in cpu partial slabs in set_cpu_partial(). This should achieve roughly similar contention on the barn spin lock as there's currently for node list_lock without sheaves, to make benchmarking results comparable. It can be further tuned later. Don't enable sheaves for bootstrap caches as that wouldn't work. In order to recognize them by SLAB_NO_OBJ_EXT, make sure the flag exists even for !CONFIG_SLAB_OBJ_EXT. This limitation will be lifted for kmalloc caches after the necessary bootstrapping changes. Also do not enable sheaves for SLAB_NOLEAKTRACE caches to avoid recursion with kmemleak tracking (thanks to Breno Leitao). Reviewed-by: Suren Baghdasaryan <surenb@google.com> Reviewed-by: Harry Yoo <harry.yoo@oracle.com> Reviewed-by: Hao Li <hao.li@linux.dev> Tested-by: Breno Leitao <leitao@debian.org> Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com> Tested-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
1 parent 4b038a9 commit e47c897

2 files changed

Lines changed: 52 additions & 10 deletions

File tree

include/linux/slab.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ enum _slab_flag_bits {
5757
#endif
5858
_SLAB_OBJECT_POISON,
5959
_SLAB_CMPXCHG_DOUBLE,
60-
#ifdef CONFIG_SLAB_OBJ_EXT
6160
_SLAB_NO_OBJ_EXT,
62-
#endif
6361
_SLAB_FLAGS_LAST_BIT
6462
};
6563

@@ -238,11 +236,7 @@ enum _slab_flag_bits {
238236
#define SLAB_TEMPORARY SLAB_RECLAIM_ACCOUNT /* Objects are short-lived */
239237

240238
/* Slab created using create_boot_cache */
241-
#ifdef CONFIG_SLAB_OBJ_EXT
242239
#define SLAB_NO_OBJ_EXT __SLAB_FLAG_BIT(_SLAB_NO_OBJ_EXT)
243-
#else
244-
#define SLAB_NO_OBJ_EXT __SLAB_FLAG_UNUSED
245-
#endif
246240

247241
/*
248242
* ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.

mm/slub.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7893,6 +7893,53 @@ static void set_cpu_partial(struct kmem_cache *s)
78937893
#endif
78947894
}
78957895

7896+
static unsigned int calculate_sheaf_capacity(struct kmem_cache *s,
7897+
struct kmem_cache_args *args)
7898+
7899+
{
7900+
unsigned int capacity;
7901+
size_t size;
7902+
7903+
7904+
if (IS_ENABLED(CONFIG_SLUB_TINY) || s->flags & SLAB_DEBUG_FLAGS)
7905+
return 0;
7906+
7907+
/*
7908+
* Bootstrap caches can't have sheaves for now (SLAB_NO_OBJ_EXT).
7909+
* SLAB_NOLEAKTRACE caches (e.g., kmemleak's object_cache) must not
7910+
* have sheaves to avoid recursion when sheaf allocation triggers
7911+
* kmemleak tracking.
7912+
*/
7913+
if (s->flags & (SLAB_NO_OBJ_EXT | SLAB_NOLEAKTRACE))
7914+
return 0;
7915+
7916+
/*
7917+
* For now we use roughly similar formula (divided by two as there are
7918+
* two percpu sheaves) as what was used for percpu partial slabs, which
7919+
* should result in similar lock contention (barn or list_lock)
7920+
*/
7921+
if (s->size >= PAGE_SIZE)
7922+
capacity = 4;
7923+
else if (s->size >= 1024)
7924+
capacity = 12;
7925+
else if (s->size >= 256)
7926+
capacity = 26;
7927+
else
7928+
capacity = 60;
7929+
7930+
/* Increment capacity to make sheaf exactly a kmalloc size bucket */
7931+
size = struct_size_t(struct slab_sheaf, objects, capacity);
7932+
size = kmalloc_size_roundup(size);
7933+
capacity = (size - struct_size_t(struct slab_sheaf, objects, 0)) / sizeof(void *);
7934+
7935+
/*
7936+
* Respect an explicit request for capacity that's typically motivated by
7937+
* expected maximum size of kmem_cache_prefill_sheaf() to not end up
7938+
* using low-performance oversize sheaves
7939+
*/
7940+
return max(capacity, args->sheaf_capacity);
7941+
}
7942+
78967943
/*
78977944
* calculate_sizes() determines the order and the distribution of data within
78987945
* a slab object.
@@ -8027,6 +8074,10 @@ static int calculate_sizes(struct kmem_cache_args *args, struct kmem_cache *s)
80278074
if (s->flags & SLAB_RECLAIM_ACCOUNT)
80288075
s->allocflags |= __GFP_RECLAIMABLE;
80298076

8077+
/* kmalloc caches need extra care to support sheaves */
8078+
if (!is_kmalloc_cache(s))
8079+
s->sheaf_capacity = calculate_sheaf_capacity(s, args);
8080+
80308081
/*
80318082
* Determine the number of objects per slab
80328083
*/
@@ -8631,15 +8682,12 @@ int do_kmem_cache_create(struct kmem_cache *s, const char *name,
86318682

86328683
set_cpu_partial(s);
86338684

8634-
if (args->sheaf_capacity && !IS_ENABLED(CONFIG_SLUB_TINY)
8635-
&& !(s->flags & SLAB_DEBUG_FLAGS)) {
8685+
if (s->sheaf_capacity) {
86368686
s->cpu_sheaves = alloc_percpu(struct slub_percpu_sheaves);
86378687
if (!s->cpu_sheaves) {
86388688
err = -ENOMEM;
86398689
goto out;
86408690
}
8641-
// TODO: increase capacity to grow slab_sheaf up to next kmalloc size?
8642-
s->sheaf_capacity = args->sheaf_capacity;
86438691
}
86448692

86458693
#ifdef CONFIG_NUMA

0 commit comments

Comments
 (0)