]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/cgroup: include slab in test_percpu_basic memory check
authorLi Wang <li.wang@linux.dev>
Fri, 1 May 2026 02:20:58 +0000 (10:20 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 29 May 2026 04:05:07 +0000 (21:05 -0700)
test_percpu_basic() currently compares memory.current against only
memory.stat:percpu after creating 1000 child cgroups.

Observed failure:
  #./test_kmem
  ok 1 test_kmem_basic
  ok 2 test_kmem_memcg_deletion
  ok 3 test_kmem_proc_kpagecgroup
  ok 4 test_kmem_kernel_stacks
  ok 5 test_kmem_dead_cgroups
  memory.current 11530240
  percpu 8440000
  not ok 6 test_percpu_basic

That assumption is too strict: child cgroup creation also allocates
slab-backed metadata, so memory.current is expected to be larger than
percpu alone. One visible path is:

  cgroup_mkdir()
    cgroup_create()
      cgroup_addrm_file()
        cgroup_add_file()
          __kernfs_create_file()
            __kernfs_new_node()
              kmem_cache_zalloc()

These kernfs allocations are charged as slab and show up in
memory.stat:slab.

Update the check to compare memory.current against (percpu + slab)
within MAX_VMSTAT_ERROR, and print slab/delta in the failure message to
improve diagnostics.

Link: https://lore.kernel.org/20260501022058.18024-3-li.wang@linux.dev
Signed-off-by: Li Wang <li.wang@linux.dev>
Reviewed-by: Waiman Long <longman@redhat.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Sayali Patil <sayalip@linux.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
tools/testing/selftests/cgroup/test_kmem.c

index 69cb1b50988c484482248dc6d93546bbf355ee88..1db0ba1226b9bf5ddea13d21f36cd280ea8feadf 100644 (file)
@@ -353,7 +353,7 @@ static int test_percpu_basic(const char *root)
 {
        int ret = KSFT_FAIL;
        char *parent, *child;
-       long current, percpu;
+       long current, percpu, slab;
        int i;
 
        parent = cg_name(root, "percpu_basic_test");
@@ -383,13 +383,14 @@ static int test_percpu_basic(const char *root)
 
        current = cg_read_long(parent, "memory.current");
        percpu = cg_read_key_long(parent, "memory.stat", "percpu ");
+       slab = cg_read_key_long(parent, "memory.stat", "slab ");
 
-       if (current > 0 && percpu > 0 && labs(current - percpu) <
-           MAX_VMSTAT_ERROR)
+       if (current > 0 && percpu > 0 && slab >= 0 &&
+                       labs(current - (percpu + slab)) < MAX_VMSTAT_ERROR)
                ret = KSFT_PASS;
        else
-               printf("memory.current %ld\npercpu %ld\n",
-                      current, percpu);
+               printf("memory.current %ld\npercpu %ld\nslab %ld\ndelta %ld\n",
+                       current, percpu, slab, current - (percpu + slab));
 
 cleanup_children:
        for (i = 0; i < 1000; i++) {