slub: fix sysfs duplicate filename creation when slub_debug=O
authorMiles Chen <>
Thu, 16 Nov 2017 01:32:25 +0000 (17:32 -0800)
committerLinus Torvalds <>
Thu, 16 Nov 2017 02:21:01 +0000 (18:21 -0800)
When slub_debug=O is set.  It is possible to clear debug flags for an
"unmergeable" slab cache in kmem_cache_open().  It makes the "unmergeable"
cache became "mergeable" in sysfs_slab_add().

These caches will generate their "unique IDs" by create_unique_id(), but
it is possible to create identical unique IDs.  In my experiment,
sgpool-128, names_cache, biovec-256 generate the same ID ":Ft-0004096" and
the kernel reports "sysfs: cannot create duplicate filename

To repeat my experiment, set disable_higher_order_debug=1,
CONFIG_SLUB_DEBUG_ON=y in kernel-4.14.

Fix this issue by setting unmergeable=1 if slub_debug=O and the the
default slub_debug contains any no-merge flags.

call path:
  __kmem_cache_alias() -> we set SLAB_NEVER_MERGE flags here
      kmem_cache_open() -> clear DEBUG_METADATA_FLAGS
      sysfs_slab_add() -> the slab cache is mergeable now

  sysfs: cannot create duplicate filename '/kernel/slab/:Ft-0004096'
  ------------[ cut here ]------------
  WARNING: CPU: 0 PID: 1 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x60/0x7c
  Modules linked in:
  CPU: 0 PID: 1 Comm: swapper/0 Tainted: G        W       4.14.0-rc7ajb-00131-gd4c2e9f-dirty #123
  Hardware name: linux,dummy-virt (DT)
  task: ffffffc07d4e0080 task.stack: ffffff8008008000
  PC is at sysfs_warn_dup+0x60/0x7c
  LR is at sysfs_warn_dup+0x60/0x7c
  pc :  lr :  pstate: 60000145
  Call trace:

Signed-off-by: Miles Chen <>
Acked-by: Christoph Lameter <>
Cc: Pekka Enberg <>
Cc: David Rientjes <>
Cc: Joonsoo Kim <>
Signed-off-by: Andrew Morton <>
Signed-off-by: Linus Torvalds <>

index 33957fd376ae5f171170179525cafce127464f9c..51484f0fc06878b6c757248d3f7c92988033014d 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5706,6 +5706,10 @@ static int sysfs_slab_add(struct kmem_cache *s)
                return 0;
+       if (!unmergeable && disable_higher_order_debug &&
+                       (slub_debug & DEBUG_METADATA_FLAGS))
+               unmergeable = 1;
        if (unmergeable) {
                 * Slabcache can never be merged so we can use the name proper.