slab, slub: remove size disparity on debug kernel
authorShakeel Butt <>
Thu, 5 Apr 2018 23:21:50 +0000 (16:21 -0700)
committerLinus Torvalds <>
Fri, 6 Apr 2018 04:36:24 +0000 (21:36 -0700)
I have noticed on debug kernel with SLAB, the size of some non-root
slabs were larger than their corresponding root slabs.

e.g. for radix_tree_node:
  $cat /proc/slabinfo | grep radix
  name     <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> ...
  radix_tree_node 15052    15075      4096         1             1 ...

  $cat /cgroup/memory/temp/memory.kmem.slabinfo | grep radix
  name     <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> ...
  radix_tree_node 1581      158       4120         1             2 ...

However for SLUB in debug kernel, the sizes were same.  On further
inspection it is found that SLUB always use kmem_cache.object_size to
measure the kmem_cache.size while SLAB use the given kmem_cache.size.
In the debug kernel the slab's size can be larger than its object_size.
Thus in the creation of non-root slab, the SLAB uses the root's size as
base to calculate the non-root slab's size and thus non-root slab's size
can be larger than the root slab's size.  For SLUB, the non-root slab's
size is measured based on the root's object_size and thus the size will
remain same for root and non-root slab.

This patch makes slab's object_size the default base to measure the
slab's size.

Fixes: 794b1248be4e ("memcg, slab: separate memcg vs root cache creation paths")
Signed-off-by: Shakeel Butt <>
Cc: Christoph Lameter <>
Cc: Pekka Enberg <>
Cc: David Rientjes <>
Cc: Joonsoo Kim <>
Cc: Vladimir Davydov <>
Signed-off-by: Andrew Morton <>
Signed-off-by: Linus Torvalds <>

index e2e2485b3496464f306c16a9e8970218abfe57f7..4a4bd71ab7284ae97e9e8f9d99f06d95525f1420 100644 (file)
@@ -379,7 +379,7 @@ struct kmem_cache *find_mergeable(unsigned int size, unsigned int align,
 static struct kmem_cache *create_cache(const char *name,
-               unsigned int object_size, unsigned int size, unsigned int align,
+               unsigned int object_size, unsigned int align,
                slab_flags_t flags, unsigned int useroffset,
                unsigned int usersize, void (*ctor)(void *),
                struct mem_cgroup *memcg, struct kmem_cache *root_cache)
@@ -396,8 +396,7 @@ static struct kmem_cache *create_cache(const char *name,
                goto out;
        s->name = name;
-       s->object_size = object_size;
-       s->size = size;
+       s->size = s->object_size = object_size;
        s->align = align;
        s->ctor = ctor;
        s->useroffset = useroffset;
@@ -503,7 +502,7 @@ kmem_cache_create_usercopy(const char *name,
                goto out_unlock;
-       s = create_cache(cache_name, size, size,
+       s = create_cache(cache_name, size,
                         calculate_alignment(flags, align, size),
                         flags, useroffset, usersize, ctor, NULL, NULL);
        if (IS_ERR(s)) {
@@ -650,7 +649,7 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg,
                goto out_unlock;
        s = create_cache(cache_name, root_cache->object_size,
-                        root_cache->size, root_cache->align,
+                        root_cache->align,
                         root_cache->flags & CACHE_CREATE_MASK,
                         root_cache->useroffset, root_cache->usersize,
                         root_cache->ctor, memcg, root_cache);