[PATCH] mm/slub: use stackdepot to save stack trace in objects

2021-04-14 Thread glittao
From: Oliver Glitta 

Many stack traces are similar so there are many similar arrays.
Stackdepot saves each unique stack only once.

Replace field addrs in struct track with depot_stack_handle_t handle.
Use stackdepot to save stack trace.

The benefits are smaller memory overhead and possibility to aggregate
per-cache statistics in the future using the stackdepot handle
instead of matching stacks manually.

Signed-off-by: Oliver Glitta 
---
 init/Kconfig |  1 +
 mm/slub.c| 79 
 2 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index 37a17853433a..a4ed2daa6c41 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1891,6 +1891,7 @@ config SLUB_DEBUG
default y
bool "Enable SLUB debugging support" if EXPERT
depends on SLUB && SYSFS
+   select STACKDEPOT if STACKTRACE_SUPPORT
help
  SLUB has extensive debug support features. Disabling these can
  result in significant savings in code size. This also disables
diff --git a/mm/slub.c b/mm/slub.c
index 9c0e26ddf300..4b18499726eb 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -203,8 +204,8 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
 #define TRACK_ADDRS_COUNT 16
 struct track {
unsigned long addr; /* Called from address */
-#ifdef CONFIG_STACKTRACE
-   unsigned long addrs[TRACK_ADDRS_COUNT]; /* Called from address */
+#ifdef CONFIG_STACKDEPOT
+   depot_stack_handle_t handle;
 #endif
int cpu;/* Was running on cpu */
int pid;/* Pid context */
@@ -581,22 +582,27 @@ static struct track *get_track(struct kmem_cache *s, void 
*object,
return kasan_reset_tag(p + alloc);
 }
 
+#ifdef CONFIG_STACKDEPOT
+static depot_stack_handle_t save_stack_trace(gfp_t flags)
+{
+   unsigned long entries[TRACK_ADDRS_COUNT];
+   depot_stack_handle_t handle;
+   unsigned int nr_entries;
+
+   nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 4);
+   handle = stack_depot_save(entries, nr_entries, flags);
+   return handle;
+}
+#endif
+
 static void set_track(struct kmem_cache *s, void *object,
enum track_item alloc, unsigned long addr)
 {
struct track *p = get_track(s, object, alloc);
 
if (addr) {
-#ifdef CONFIG_STACKTRACE
-   unsigned int nr_entries;
-
-   metadata_access_enable();
-   nr_entries = stack_trace_save(kasan_reset_tag(p->addrs),
- TRACK_ADDRS_COUNT, 3);
-   metadata_access_disable();
-
-   if (nr_entries < TRACK_ADDRS_COUNT)
-   p->addrs[nr_entries] = 0;
+#ifdef CONFIG_STACKDEPOT
+   p->handle = save_stack_trace(GFP_KERNEL);
 #endif
p->addr = addr;
p->cpu = smp_processor_id();
@@ -623,14 +629,19 @@ static void print_track(const char *s, struct track *t, 
unsigned long pr_time)
 
pr_err("%s in %pS age=%lu cpu=%u pid=%d\n",
   s, (void *)t->addr, pr_time - t->when, t->cpu, t->pid);
-#ifdef CONFIG_STACKTRACE
+#ifdef CONFIG_STACKDEPOT
{
-   int i;
-   for (i = 0; i < TRACK_ADDRS_COUNT; i++)
-   if (t->addrs[i])
-   pr_err("\t%pS\n", (void *)t->addrs[i]);
-   else
-   break;
+   depot_stack_handle_t handle;
+   unsigned long *entries;
+   unsigned int nr_entries;
+
+   handle = READ_ONCE(t->handle);
+   if (!handle) {
+   pr_err("object allocation/free stack trace missing\n");
+   } else {
+   nr_entries = stack_depot_fetch(handle, );
+   stack_trace_print(entries, nr_entries, 0);
+   }
}
 #endif
 }
@@ -4017,18 +4028,26 @@ void kmem_obj_info(struct kmem_obj_info *kpp, void 
*object, struct page *page)
objp = fixup_red_left(s, objp);
trackp = get_track(s, objp, TRACK_ALLOC);
kpp->kp_ret = (void *)trackp->addr;
-#ifdef CONFIG_STACKTRACE
-   for (i = 0; i < KS_ADDRS_COUNT && i < TRACK_ADDRS_COUNT; i++) {
-   kpp->kp_stack[i] = (void *)trackp->addrs[i];
-   if (!kpp->kp_stack[i])
-   break;
-   }
+#ifdef CONFIG_STACKDEPOT
+   {
+   depot_stack_handle_t handle;
+   unsigned long *entries;
+   unsigned int nr_entries;
 
-   trackp = get_track(s, objp, TRACK_FREE);
-   for (i = 0; i < KS_ADDRS_COUNT && i < TRACK_ADDRS_COUNT; i++) {
-   kpp->kp_free_stack[i] = (void *)trackp->addrs[i];
-   if (!kpp->kp_free_stack[i])
-   break;
+   handle = READ_ONCE(trackp->handle);

[PATCH v4 2/3] mm/slub, kunit: add a KUnit test for SLUB debugging functionality

2021-04-13 Thread glittao
From: Oliver Glitta 

SLUB has resiliency_test() function which is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it. KUnit should be a proper replacement for it.

Try changing byte in redzone after allocation and changing
pointer to next free node, first byte, 50th byte and redzone
byte. Check if validation finds errors.

There are several differences from the original resiliency test:
Tests create own caches with known state instead of corrupting
shared kmalloc caches.

The corruption of freepointer uses correct offset, the original
resiliency test got broken with freepointer changes.

Scratch changing random byte test, because it does not have
meaning in this form where we need deterministic results.

Add new option CONFIG_SLUB_KUNIT_TEST in Kconfig.
Because the test deliberatly modifies non-allocated objects, it depends on
!KASAN which would have otherwise prevented that.

Use kunit_resource to count errors in cache and silence bug reports.
Count error whenever slab_bug() or slab_fix() is called or when
the count of pages is wrong.

Signed-off-by: Oliver Glitta 
---
Changes since v3

Use kunit_resource to silence bug reports and count errors suggested by
Marco Elver.
Make the test depends on !KASAN thanks to report from the kernel test robot.

Changes since v2

Use bit operation & instead of logical && as reported by kernel test
robot and Dan Carpenter

Changes since v1

Conversion from kselftest to KUnit test suggested by Marco Elver.
Error silencing.
Error counting improvements.
 lib/Kconfig.debug |  12 
 lib/Makefile  |   1 +
 lib/slub_kunit.c  | 150 ++
 mm/slab.h |   1 +
 mm/slub.c |  50 ++--
 5 files changed, 209 insertions(+), 5 deletions(-)
 create mode 100644 lib/slub_kunit.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2779c29d9981..9b8a0d754278 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2371,6 +2371,18 @@ config BITS_TEST
 
  If unsure, say N.
 
+config SLUB_KUNIT_TEST
+   tristate "KUnit test for SLUB cache error detection" if !KUNIT_ALL_TESTS
+   depends on SLUB_DEBUG && KUNIT && !KASAN
+   default KUNIT_ALL_TESTS
+   help
+ This builds SLUB allocator unit test.
+ Tests SLUB cache debugging functionality.
+ For more information on KUnit and unit tests in general please refer
+ to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+ If unsure, say N.
+
 config TEST_UDELAY
tristate "udelay test driver"
help
diff --git a/lib/Makefile b/lib/Makefile
index b5307d3eec1a..1e59c6714ed8 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -352,5 +352,6 @@ obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
 obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
 obj-$(CONFIG_BITS_TEST) += test_bits.o
 obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
+obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c
new file mode 100644
index ..cb9ae9f7e8a6
--- /dev/null
+++ b/lib/slub_kunit.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../mm/slab.h"
+
+static struct kunit_resource resource;
+static int slab_errors;
+
+static void test_clobber_zone(struct kunit *test)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_alloc", 64, 0,
+   SLAB_RED_ZONE, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   p[64] = 0x12;
+
+   validate_slab_cache(s);
+   KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+   kmem_cache_free(s, p);
+   kmem_cache_destroy(s);
+}
+
+static void test_next_pointer(struct kunit *test)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_next_ptr_free", 64, 
0,
+   SLAB_POISON, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+   unsigned long tmp;
+   unsigned long *ptr_addr;
+
+   kmem_cache_free(s, p);
+
+   ptr_addr = (unsigned long *)(p + s->offset);
+   tmp = *ptr_addr;
+   p[s->offset] = 0x12;
+
+   /*
+* Expecting three errors.
+* One for the corrupted freechain and the other one for the wrong
+* count of objects in use. The third error is fixing broken cache.
+*/
+   validate_slab_cache(s);
+   KUNIT_EXPECT_EQ(test, 3, slab_errors);
+
+   /*
+* Try to repair corrupted freepointer.
+* Still expecting two errors. The first for the wrong count
+* of objects in use.
+* The second error is for fixing broken cache.
+*/
+   *ptr_addr = tmp;
+   slab_errors = 0;
+
+   validate_slab_cache(s);
+   KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+   /*
+* Previous validation repaired the count of objects in use.
+* Now 

[PATCH v4 1/3] kunit: make test->lock irq safe

2021-04-13 Thread glittao
From: Vlastimil Babka 

The upcoming SLUB kunit test will be calling kunit_find_named_resource() from
a context with disabled interrupts. That means kunit's test->lock needs to be
IRQ safe to avoid potential deadlocks and lockdep splats.

This patch therefore changes the test->lock usage to spin_lock_irqsave()
and spin_unlock_irqrestore().

Signed-off-by: Vlastimil Babka 
Signed-off-by: Oliver Glitta 
---
 include/kunit/test.h |  5 +++--
 lib/kunit/test.c | 18 +++---
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/include/kunit/test.h b/include/kunit/test.h
index 49601c4b98b8..524d4789af22 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -515,8 +515,9 @@ kunit_find_resource(struct kunit *test,
void *match_data)
 {
struct kunit_resource *res, *found = NULL;
+   unsigned long flags;
 
-   spin_lock(>lock);
+   spin_lock_irqsave(>lock, flags);
 
list_for_each_entry_reverse(res, >resources, node) {
if (match(test, res, (void *)match_data)) {
@@ -526,7 +527,7 @@ kunit_find_resource(struct kunit *test,
}
}
 
-   spin_unlock(>lock);
+   spin_unlock_irqrestore(>lock, flags);
 
return found;
 }
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index ec9494e914ef..2c62eeb45b82 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -442,6 +442,7 @@ int kunit_add_resource(struct kunit *test,
   void *data)
 {
int ret = 0;
+   unsigned long flags;
 
res->free = free;
kref_init(>refcount);
@@ -454,10 +455,10 @@ int kunit_add_resource(struct kunit *test,
res->data = data;
}
 
-   spin_lock(>lock);
+   spin_lock_irqsave(>lock, flags);
list_add_tail(>node, >resources);
/* refcount for list is established by kref_init() */
-   spin_unlock(>lock);
+   spin_unlock_irqrestore(>lock, flags);
 
return ret;
 }
@@ -515,9 +516,11 @@ EXPORT_SYMBOL_GPL(kunit_alloc_and_get_resource);
 
 void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)
 {
-   spin_lock(>lock);
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
list_del(>node);
-   spin_unlock(>lock);
+   spin_unlock_irqrestore(>lock, flags);
kunit_put_resource(res);
 }
 EXPORT_SYMBOL_GPL(kunit_remove_resource);
@@ -597,6 +600,7 @@ EXPORT_SYMBOL_GPL(kunit_kfree);
 void kunit_cleanup(struct kunit *test)
 {
struct kunit_resource *res;
+   unsigned long flags;
 
/*
 * test->resources is a stack - each allocation must be freed in the
@@ -608,9 +612,9 @@ void kunit_cleanup(struct kunit *test)
 * protect against the current node being deleted, not the next.
 */
while (true) {
-   spin_lock(>lock);
+   spin_lock_irqsave(>lock, flags);
if (list_empty(>resources)) {
-   spin_unlock(>lock);
+   spin_unlock_irqrestore(>lock, flags);
break;
}
res = list_last_entry(>resources,
@@ -621,7 +625,7 @@ void kunit_cleanup(struct kunit *test)
 * resource, and this can't happen if the test->lock
 * is held.
 */
-   spin_unlock(>lock);
+   spin_unlock_irqrestore(>lock, flags);
kunit_remove_resource(test, res);
}
 #if (IS_ENABLED(CONFIG_KASAN) && IS_ENABLED(CONFIG_KUNIT))
-- 
2.31.1.272.g89b43f80a5



[PATCH v4 3/3] slub: remove resiliency_test() function

2021-04-13 Thread glittao
From: Oliver Glitta 

Function resiliency_test() is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it.

This function is replaced with KUnit test for SLUB added
by the previous patch "selftests: add a KUnit test for SLUB
debugging functionality".

Signed-off-by: Oliver Glitta 

Acked-by: Vlastimil Babka 
Acked-by: David Rientjes 
---
 mm/slub.c | 64 ---
 1 file changed, 64 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index d7df8841d90a..c65e2c471a13 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -154,9 +154,6 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
  * - Variable sizing of the per node arrays
  */
 
-/* Enable to test recovery from slab corruption on boot */
-#undef SLUB_RESILIENCY_TEST
-
 /* Enable to log cmpxchg failures */
 #undef SLUB_DEBUG_CMPXCHG
 
@@ -4939,66 +4936,6 @@ static int list_locations(struct kmem_cache *s, char 
*buf,
 }
 #endif /* CONFIG_SLUB_DEBUG */
 
-#ifdef SLUB_RESILIENCY_TEST
-static void __init resiliency_test(void)
-{
-   u8 *p;
-   int type = KMALLOC_NORMAL;
-
-   BUILD_BUG_ON(KMALLOC_MIN_SIZE > 16 || KMALLOC_SHIFT_HIGH < 10);
-
-   pr_err("SLUB resiliency testing\n");
-   pr_err("---\n");
-   pr_err("A. Corruption after allocation\n");
-
-   p = kzalloc(16, GFP_KERNEL);
-   p[16] = 0x12;
-   pr_err("\n1. kmalloc-16: Clobber Redzone/next pointer 0x12->0x%p\n\n",
-  p + 16);
-
-   validate_slab_cache(kmalloc_caches[type][4]);
-
-   /* Hmmm... The next two are dangerous */
-   p = kzalloc(32, GFP_KERNEL);
-   p[32 + sizeof(void *)] = 0x34;
-   pr_err("\n2. kmalloc-32: Clobber next pointer/next slab 0x34 -> 
-0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-
-   validate_slab_cache(kmalloc_caches[type][5]);
-   p = kzalloc(64, GFP_KERNEL);
-   p += 64 + (get_cycles() & 0xff) * sizeof(void *);
-   *p = 0x56;
-   pr_err("\n3. kmalloc-64: corrupting random byte 0x56->0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-   validate_slab_cache(kmalloc_caches[type][6]);
-
-   pr_err("\nB. Corruption after free\n");
-   p = kzalloc(128, GFP_KERNEL);
-   kfree(p);
-   *p = 0x78;
-   pr_err("1. kmalloc-128: Clobber first word 0x78->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][7]);
-
-   p = kzalloc(256, GFP_KERNEL);
-   kfree(p);
-   p[50] = 0x9a;
-   pr_err("\n2. kmalloc-256: Clobber 50th byte 0x9a->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][8]);
-
-   p = kzalloc(512, GFP_KERNEL);
-   kfree(p);
-   p[512] = 0xab;
-   pr_err("\n3. kmalloc-512: Clobber redzone 0xab->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][9]);
-}
-#else
-#ifdef CONFIG_SYSFS
-static void resiliency_test(void) {};
-#endif
-#endif /* SLUB_RESILIENCY_TEST */
-
 #ifdef CONFIG_SYSFS
 enum slab_stat_type {
SL_ALL, /* All slabs */
@@ -5847,7 +5784,6 @@ static int __init slab_sysfs_init(void)
}
 
mutex_unlock(_mutex);
-   resiliency_test();
return 0;
 }
 
-- 
2.31.1.272.g89b43f80a5



[PATCH v3 2/2] slub: remove resiliency_test() function

2021-03-31 Thread glittao
From: Oliver Glitta 

Function resiliency_test() is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it.

This function is replaced with KUnit test for SLUB added
by the previous patch "selftests: add a KUnit test for SLUB
debugging functionality".

Signed-off-by: Oliver Glitta 

Acked-by: Vlastimil Babka 
Acked-by: David Rientjes 
---
 mm/slub.c | 64 ---
 1 file changed, 64 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 7083e89432d0..6eff5754895f 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -153,9 +153,6 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
  * - Variable sizing of the per node arrays
  */
 
-/* Enable to test recovery from slab corruption on boot */
-#undef SLUB_RESILIENCY_TEST
-
 /* Enable to log cmpxchg failures */
 #undef SLUB_DEBUG_CMPXCHG
 
@@ -4923,66 +4920,6 @@ static int list_locations(struct kmem_cache *s, char 
*buf,
 }
 #endif /* CONFIG_SLUB_DEBUG */
 
-#ifdef SLUB_RESILIENCY_TEST
-static void __init resiliency_test(void)
-{
-   u8 *p;
-   int type = KMALLOC_NORMAL;
-
-   BUILD_BUG_ON(KMALLOC_MIN_SIZE > 16 || KMALLOC_SHIFT_HIGH < 10);
-
-   pr_err("SLUB resiliency testing\n");
-   pr_err("---\n");
-   pr_err("A. Corruption after allocation\n");
-
-   p = kzalloc(16, GFP_KERNEL);
-   p[16] = 0x12;
-   pr_err("\n1. kmalloc-16: Clobber Redzone/next pointer 0x12->0x%p\n\n",
-  p + 16);
-
-   validate_slab_cache(kmalloc_caches[type][4]);
-
-   /* Hmmm... The next two are dangerous */
-   p = kzalloc(32, GFP_KERNEL);
-   p[32 + sizeof(void *)] = 0x34;
-   pr_err("\n2. kmalloc-32: Clobber next pointer/next slab 0x34 -> 
-0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-
-   validate_slab_cache(kmalloc_caches[type][5]);
-   p = kzalloc(64, GFP_KERNEL);
-   p += 64 + (get_cycles() & 0xff) * sizeof(void *);
-   *p = 0x56;
-   pr_err("\n3. kmalloc-64: corrupting random byte 0x56->0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-   validate_slab_cache(kmalloc_caches[type][6]);
-
-   pr_err("\nB. Corruption after free\n");
-   p = kzalloc(128, GFP_KERNEL);
-   kfree(p);
-   *p = 0x78;
-   pr_err("1. kmalloc-128: Clobber first word 0x78->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][7]);
-
-   p = kzalloc(256, GFP_KERNEL);
-   kfree(p);
-   p[50] = 0x9a;
-   pr_err("\n2. kmalloc-256: Clobber 50th byte 0x9a->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][8]);
-
-   p = kzalloc(512, GFP_KERNEL);
-   kfree(p);
-   p[512] = 0xab;
-   pr_err("\n3. kmalloc-512: Clobber redzone 0xab->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][9]);
-}
-#else
-#ifdef CONFIG_SYSFS
-static void resiliency_test(void) {};
-#endif
-#endif /* SLUB_RESILIENCY_TEST */
-
 #ifdef CONFIG_SYSFS
 enum slab_stat_type {
SL_ALL, /* All slabs */
@@ -5831,7 +5768,6 @@ static int __init slab_sysfs_init(void)
}
 
mutex_unlock(_mutex);
-   resiliency_test();
return 0;
 }
 
-- 
2.17.1



[PATCH v3 1/2] kunit: add a KUnit test for SLUB debugging functionality

2021-03-31 Thread glittao
From: Oliver Glitta 

SLUB has resiliency_test() function which is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it. KUnit should be a proper replacement for it.

Try changing byte in redzone after allocation and changing
pointer to next free node, first byte, 50th byte and redzone
byte. Check if validation finds errors.

There are several differences from the original resiliency test:
Tests create own caches with known state instead of corrupting
shared kmalloc caches.

The corruption of freepointer uses correct offset, the original
resiliency test got broken with freepointer changes.

Scratch changing random byte test, because it does not have
meaning in this form where we need deterministic results.

Add new option CONFIG_SLUB_KUNIT_TEST in Kconfig.

Add a counter field "errors" to struct kmem_cache to count number
of errors detected in cache.

Silence bug report in SLUB test. Add SLAB_SILENT_ERRORS debug flag.
Add SLAB_SILENT_ERRORS flag to SLAB_NEVER_MERGE, SLAB_DEBUG_FLAGS,
SLAB_FLAGS_PERMITTED macros.

Signed-off-by: Oliver Glitta 
---
Changes since v2

Use bit operation & instead of logical && as reported by kernel test 
robot and Dan Carpenter

Changes since v1

Conversion from kselftest to KUnit test suggested by Marco Elver.
Error silencing.
Error counting improvements. 

 include/linux/slab.h |   2 +
 include/linux/slub_def.h |   2 +
 lib/Kconfig.debug|   5 ++
 lib/Makefile |   1 +
 lib/test_slub.c  | 124 +++
 mm/slab.h|   7 ++-
 mm/slab_common.c |   2 +-
 mm/slub.c|  64 +---
 8 files changed, 184 insertions(+), 23 deletions(-)
 create mode 100644 lib/test_slub.c

diff --git a/include/linux/slab.h b/include/linux/slab.h
index 7ae604076767..ed1a5a64d028 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -25,6 +25,8 @@
  */
 /* DEBUG: Perform (expensive) checks on alloc/free */
 #define SLAB_CONSISTENCY_CHECKS((slab_flags_t __force)0x0100U)
+/* DEBUG: Silent bug reports */
+#define SLAB_SILENT_ERRORS ((slab_flags_t __force)0x0200U)
 /* DEBUG: Red zone objs in a cache */
 #define SLAB_RED_ZONE  ((slab_flags_t __force)0x0400U)
 /* DEBUG: Poison objects */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index dcde82a4434c..e4b51bb5bb83 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -133,6 +133,8 @@ struct kmem_cache {
unsigned int usersize;  /* Usercopy region size */
 
struct kmem_cache_node *node[MAX_NUMNODES];
+
+   int errors; /* Number of errors in cache */
 };
 
 #ifdef CONFIG_SLUB_CPU_PARTIAL
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2779c29d9981..e0dec830c269 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2371,6 +2371,11 @@ config BITS_TEST
 
  If unsure, say N.
 
+config SLUB_KUNIT_TEST
+   tristate "KUnit Test for SLUB cache error detection" if !KUNIT_ALL_TESTS
+   depends on SLUB_DEBUG && KUNIT
+   default KUNIT_ALL_TESTS
+
 config TEST_UDELAY
tristate "udelay test driver"
help
diff --git a/lib/Makefile b/lib/Makefile
index b5307d3eec1a..e1eb986c0e87 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -352,5 +352,6 @@ obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
 obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
 obj-$(CONFIG_BITS_TEST) += test_bits.o
 obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
+obj-$(CONFIG_SLUB_KUNIT_TEST) += test_slub.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
diff --git a/lib/test_slub.c b/lib/test_slub.c
new file mode 100644
index ..4f8ea3c7d867
--- /dev/null
+++ b/lib/test_slub.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../mm/slab.h"
+
+
+static void test_clobber_zone(struct kunit *test)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_alloc", 64, 0,
+   SLAB_RED_ZONE | SLAB_SILENT_ERRORS, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   p[64] = 0x12;
+
+   validate_slab_cache(s);
+   KUNIT_EXPECT_EQ(test, 1, s->errors);
+
+   kmem_cache_free(s, p);
+   kmem_cache_destroy(s);
+}
+
+static void test_next_pointer(struct kunit *test)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_next_ptr_free", 64, 
0,
+   SLAB_POISON | SLAB_SILENT_ERRORS, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+   unsigned long tmp;
+   unsigned long *ptr_addr;
+
+   kmem_cache_free(s, p);
+
+   ptr_addr = (unsigned long *)(p + s->offset);
+   tmp = *ptr_addr;
+   p[s->offset] = 0x12;
+
+   /*
+* Expecting two errors.
+* One for the corrupted freechain and the other one for the wrong
+* count of objects in use.
+*/
+ 

[PATCH v2 2/2] slub: remove resiliency_test() function

2021-03-30 Thread glittao
From: Oliver Glitta 

Function resiliency_test() is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it.

This function is replaced with KUnit test for SLUB added
by the previous patch "selftests: add a KUnit test for SLUB
debugging functionality".

Signed-off-by: Oliver Glitta 

Acked-by: Vlastimil Babka 
Acked-by: David Rientjes 
---
 mm/slub.c | 64 ---
 1 file changed, 64 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 06916e11a2bf..7270978c4e21 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -153,9 +153,6 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
  * - Variable sizing of the per node arrays
  */
 
-/* Enable to test recovery from slab corruption on boot */
-#undef SLUB_RESILIENCY_TEST
-
 /* Enable to log cmpxchg failures */
 #undef SLUB_DEBUG_CMPXCHG
 
@@ -4923,66 +4920,6 @@ static int list_locations(struct kmem_cache *s, char 
*buf,
 }
 #endif /* CONFIG_SLUB_DEBUG */
 
-#ifdef SLUB_RESILIENCY_TEST
-static void __init resiliency_test(void)
-{
-   u8 *p;
-   int type = KMALLOC_NORMAL;
-
-   BUILD_BUG_ON(KMALLOC_MIN_SIZE > 16 || KMALLOC_SHIFT_HIGH < 10);
-
-   pr_err("SLUB resiliency testing\n");
-   pr_err("---\n");
-   pr_err("A. Corruption after allocation\n");
-
-   p = kzalloc(16, GFP_KERNEL);
-   p[16] = 0x12;
-   pr_err("\n1. kmalloc-16: Clobber Redzone/next pointer 0x12->0x%p\n\n",
-  p + 16);
-
-   validate_slab_cache(kmalloc_caches[type][4]);
-
-   /* Hmmm... The next two are dangerous */
-   p = kzalloc(32, GFP_KERNEL);
-   p[32 + sizeof(void *)] = 0x34;
-   pr_err("\n2. kmalloc-32: Clobber next pointer/next slab 0x34 -> 
-0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-
-   validate_slab_cache(kmalloc_caches[type][5]);
-   p = kzalloc(64, GFP_KERNEL);
-   p += 64 + (get_cycles() & 0xff) * sizeof(void *);
-   *p = 0x56;
-   pr_err("\n3. kmalloc-64: corrupting random byte 0x56->0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-   validate_slab_cache(kmalloc_caches[type][6]);
-
-   pr_err("\nB. Corruption after free\n");
-   p = kzalloc(128, GFP_KERNEL);
-   kfree(p);
-   *p = 0x78;
-   pr_err("1. kmalloc-128: Clobber first word 0x78->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][7]);
-
-   p = kzalloc(256, GFP_KERNEL);
-   kfree(p);
-   p[50] = 0x9a;
-   pr_err("\n2. kmalloc-256: Clobber 50th byte 0x9a->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][8]);
-
-   p = kzalloc(512, GFP_KERNEL);
-   kfree(p);
-   p[512] = 0xab;
-   pr_err("\n3. kmalloc-512: Clobber redzone 0xab->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][9]);
-}
-#else
-#ifdef CONFIG_SYSFS
-static void resiliency_test(void) {};
-#endif
-#endif /* SLUB_RESILIENCY_TEST */
-
 #ifdef CONFIG_SYSFS
 enum slab_stat_type {
SL_ALL, /* All slabs */
@@ -5831,7 +5768,6 @@ static int __init slab_sysfs_init(void)
}
 
mutex_unlock(_mutex);
-   resiliency_test();
return 0;
 }
 
-- 
2.17.1



[PATCH v2 1/2] kunit: add a KUnit test for SLUB debugging functionality

2021-03-30 Thread glittao
From: Oliver Glitta 

SLUB has resiliency_test() function which is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it. KUnit should be a proper replacement for it.

Try changing byte in redzone after allocation and changing
pointer to next free node, first byte, 50th byte and redzone
byte. Check if validation finds errors.

There are several differences from the original resiliency test:
Tests create own caches with known state instead of corrupting
shared kmalloc caches.

The corruption of freepointer uses correct offset, the original
resiliency test got broken with freepointer changes.

Scratch changing random byte test, because it does not have
meaning in this form where we need deterministic results.

Add new option CONFIG_SLUB_KUNIT_TEST in Kconfig.

Add a counter field "errors" to struct kmem_cache to count number
of errors detected in cache.

Silence bug report in SLUB test. Add SLAB_SILENT_ERRORS debug flag.
Add SLAB_SILENT_ERRORS flag to SLAB_NEVER_MERGE, SLAB_DEBUG_FLAGS,
SLAB_FLAGS_PERMITTED macros.

Signed-off-by: Oliver Glitta 
---
Changes since v1

Conversion from kselftest to KUnit test suggested by Marco Elver.
Error silencing.
Error counting improvements. 

 include/linux/slab.h |   2 +
 include/linux/slub_def.h |   2 +
 lib/Kconfig.debug|   5 ++
 lib/Makefile |   1 +
 lib/test_slub.c  | 124 +++
 mm/slab.h|   7 ++-
 mm/slab_common.c |   2 +-
 mm/slub.c|  64 +---
 8 files changed, 184 insertions(+), 23 deletions(-)
 create mode 100644 lib/test_slub.c

diff --git a/include/linux/slab.h b/include/linux/slab.h
index 7ae604076767..ed1a5a64d028 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -25,6 +25,8 @@
  */
 /* DEBUG: Perform (expensive) checks on alloc/free */
 #define SLAB_CONSISTENCY_CHECKS((slab_flags_t __force)0x0100U)
+/* DEBUG: Silent bug reports */
+#define SLAB_SILENT_ERRORS ((slab_flags_t __force)0x0200U)
 /* DEBUG: Red zone objs in a cache */
 #define SLAB_RED_ZONE  ((slab_flags_t __force)0x0400U)
 /* DEBUG: Poison objects */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index dcde82a4434c..e4b51bb5bb83 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -133,6 +133,8 @@ struct kmem_cache {
unsigned int usersize;  /* Usercopy region size */
 
struct kmem_cache_node *node[MAX_NUMNODES];
+
+   int errors; /* Number of errors in cache */
 };
 
 #ifdef CONFIG_SLUB_CPU_PARTIAL
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2779c29d9981..e0dec830c269 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2371,6 +2371,11 @@ config BITS_TEST
 
  If unsure, say N.
 
+config SLUB_KUNIT_TEST
+   tristate "KUnit Test for SLUB cache error detection" if !KUNIT_ALL_TESTS
+   depends on SLUB_DEBUG && KUNIT
+   default KUNIT_ALL_TESTS
+
 config TEST_UDELAY
tristate "udelay test driver"
help
diff --git a/lib/Makefile b/lib/Makefile
index b5307d3eec1a..e1eb986c0e87 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -352,5 +352,6 @@ obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
 obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
 obj-$(CONFIG_BITS_TEST) += test_bits.o
 obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
+obj-$(CONFIG_SLUB_KUNIT_TEST) += test_slub.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
diff --git a/lib/test_slub.c b/lib/test_slub.c
new file mode 100644
index ..4f8ea3c7d867
--- /dev/null
+++ b/lib/test_slub.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "../mm/slab.h"
+
+
+static void test_clobber_zone(struct kunit *test)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_alloc", 64, 0,
+   SLAB_RED_ZONE | SLAB_SILENT_ERRORS, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   p[64] = 0x12;
+
+   validate_slab_cache(s);
+   KUNIT_EXPECT_EQ(test, 1, s->errors);
+
+   kmem_cache_free(s, p);
+   kmem_cache_destroy(s);
+}
+
+static void test_next_pointer(struct kunit *test)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_next_ptr_free", 64, 
0,
+   SLAB_POISON | SLAB_SILENT_ERRORS, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+   unsigned long tmp;
+   unsigned long *ptr_addr;
+
+   kmem_cache_free(s, p);
+
+   ptr_addr = (unsigned long *)(p + s->offset);
+   tmp = *ptr_addr;
+   p[s->offset] = 0x12;
+
+   /*
+* Expecting two errors.
+* One for the corrupted freechain and the other one for the wrong
+* count of objects in use.
+*/
+   validate_slab_cache(s);
+   KUNIT_EXPECT_EQ(test, 2, s->errors);
+
+   /*
+* Try to repair 

[PATCH 1/2] selftests: add a kselftest for SLUB debugging functionality

2021-03-16 Thread glittao
From: Oliver Glitta 

SLUB has resiliency_test() function which is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it. Kselftest should proper replacement for it.

Try changing byte in redzone after allocation and changing
pointer to next free node, first byte, 50th byte and redzone
byte. Check if validation finds errors.

There are several differences from the original resiliency test:
Tests create own caches with known state instead of corrupting
shared kmalloc caches.

The corruption of freepointer uses correct offset, the original
resiliency test got broken with freepointer changes.

Scratch changing random byte test, because it does not have
meaning in this form where we need deterministic results.

Add new option CONFIG_TEST_SLUB in Kconfig.

Add parameter to function validate_slab_cache() to return
number of errors in cache.

Signed-off-by: Oliver Glitta 
---
 lib/Kconfig.debug|   4 +
 lib/Makefile |   1 +
 lib/test_slub.c  | 125 +++
 mm/slab.h|   1 +
 mm/slub.c|  34 +---
 tools/testing/selftests/lib/Makefile |   2 +-
 tools/testing/selftests/lib/config   |   1 +
 tools/testing/selftests/lib/slub.sh  |   3 +
 8 files changed, 159 insertions(+), 12 deletions(-)
 create mode 100644 lib/test_slub.c
 create mode 100755 tools/testing/selftests/lib/slub.sh

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2779c29d9981..2d56092abbc4 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2123,6 +2123,10 @@ config TEST_KSTRTOX
 config TEST_PRINTF
tristate "Test printf() family of functions at runtime"
 
+config TEST_SLUB
+   tristate "Test SLUB cache errors at runtime"
+   depends on SLUB_DEBUG
+
 config TEST_BITMAP
tristate "Test bitmap_*() family of functions at runtime"
help
diff --git a/lib/Makefile b/lib/Makefile
index b5307d3eec1a..b6603803b1c4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
 obj-$(CONFIG_TEST_PRINTF) += test_printf.o
+obj-$(CONFIG_TEST_SLUB) += test_slub.o
 obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
 obj-$(CONFIG_TEST_STRSCPY) += test_strscpy.o
 obj-$(CONFIG_TEST_UUID) += test_uuid.o
diff --git a/lib/test_slub.c b/lib/test_slub.c
new file mode 100644
index ..0075d9b44251
--- /dev/null
+++ b/lib/test_slub.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for slub facility.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include "../mm/slab.h"
+
+#include "../tools/testing/selftests/kselftest_module.h"
+
+
+KSTM_MODULE_GLOBALS();
+
+
+static void __init validate_result(struct kmem_cache *s, int expected_errors)
+{
+   int errors = 0;
+
+   validate_slab_cache(s, );
+   KSTM_CHECK_ZERO(errors - expected_errors);
+}
+
+static void __init test_clobber_zone(void)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_alloc", 64, 0,
+   SLAB_RED_ZONE, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   p[64] = 0x12;
+   pr_err("1. kmem_cache: Clobber Redzone 0x12->0x%p\n", p + 64);
+
+   validate_result(s, 1);
+   kmem_cache_free(s, p);
+   kmem_cache_destroy(s);
+}
+
+static void __init test_next_pointer(void)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_next_ptr_free", 64, 
0,
+   SLAB_RED_ZONE, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   kmem_cache_free(s, p);
+   p[s->offset] = 0x12;
+   pr_err("1. kmem_cache: Clobber next pointer 0x34 -> -0x%p\n", p);
+
+   validate_result(s, 1);
+   kmem_cache_destroy(s);
+}
+
+static void __init test_first_word(void)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_1th_word_free", 64, 
0,
+   SLAB_POISON, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   kmem_cache_free(s, p);
+   *p = 0x78;
+   pr_err("2. kmem_cache: Clobber first word 0x78->0x%p\n", p);
+
+   validate_result(s, 1);
+   kmem_cache_destroy(s);
+}
+
+static void __init test_clobber_50th_byte(void)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_50th_word_free", 64, 
0,
+   SLAB_POISON, NULL);
+   u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+   kmem_cache_free(s, p);
+   p[50] = 0x9a;
+   pr_err("3. kmem_cache: Clobber 50th byte 0x9a->0x%p\n", p);
+
+   validate_result(s, 1);
+   kmem_cache_destroy(s);
+}
+
+static void __init test_clobber_redzone_free(void)
+{
+   struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_free", 64, 0,
+   SLAB_RED_ZONE, NULL);
+   u8 

[PATCH 2/2] slub: remove resiliency_test() function

2021-03-16 Thread glittao
From: Oliver Glitta 

Function resiliency_test() is hidden behind #ifdef
SLUB_RESILIENCY_TEST that is not part of Kconfig, so nobody
runs it.

This function is replaced with kselftest for SLUB added
by the previous patch "selftests: add a kselftest for SLUB
debugging functionality".

Signed-off-by: Oliver Glitta 
---
 mm/slub.c | 64 ---
 1 file changed, 64 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index c00e2b263e03..bfeb9ecd56b4 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -153,9 +153,6 @@ static inline bool kmem_cache_has_cpu_partial(struct 
kmem_cache *s)
  * - Variable sizing of the per node arrays
  */
 
-/* Enable to test recovery from slab corruption on boot */
-#undef SLUB_RESILIENCY_TEST
-
 /* Enable to log cmpxchg failures */
 #undef SLUB_DEBUG_CMPXCHG
 
@@ -4910,66 +4907,6 @@ static int list_locations(struct kmem_cache *s, char 
*buf,
 }
 #endif /* CONFIG_SLUB_DEBUG */
 
-#ifdef SLUB_RESILIENCY_TEST
-static void __init resiliency_test(void)
-{
-   u8 *p;
-   int type = KMALLOC_NORMAL;
-
-   BUILD_BUG_ON(KMALLOC_MIN_SIZE > 16 || KMALLOC_SHIFT_HIGH < 10);
-
-   pr_err("SLUB resiliency testing\n");
-   pr_err("---\n");
-   pr_err("A. Corruption after allocation\n");
-
-   p = kzalloc(16, GFP_KERNEL);
-   p[16] = 0x12;
-   pr_err("\n1. kmalloc-16: Clobber Redzone/next pointer 0x12->0x%p\n\n",
-  p + 16);
-
-   validate_slab_cache(kmalloc_caches[type][4]);
-
-   /* Hmmm... The next two are dangerous */
-   p = kzalloc(32, GFP_KERNEL);
-   p[32 + sizeof(void *)] = 0x34;
-   pr_err("\n2. kmalloc-32: Clobber next pointer/next slab 0x34 -> 
-0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-
-   validate_slab_cache(kmalloc_caches[type][5]);
-   p = kzalloc(64, GFP_KERNEL);
-   p += 64 + (get_cycles() & 0xff) * sizeof(void *);
-   *p = 0x56;
-   pr_err("\n3. kmalloc-64: corrupting random byte 0x56->0x%p\n",
-  p);
-   pr_err("If allocated object is overwritten then not detectable\n\n");
-   validate_slab_cache(kmalloc_caches[type][6]);
-
-   pr_err("\nB. Corruption after free\n");
-   p = kzalloc(128, GFP_KERNEL);
-   kfree(p);
-   *p = 0x78;
-   pr_err("1. kmalloc-128: Clobber first word 0x78->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][7]);
-
-   p = kzalloc(256, GFP_KERNEL);
-   kfree(p);
-   p[50] = 0x9a;
-   pr_err("\n2. kmalloc-256: Clobber 50th byte 0x9a->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][8]);
-
-   p = kzalloc(512, GFP_KERNEL);
-   kfree(p);
-   p[512] = 0xab;
-   pr_err("\n3. kmalloc-512: Clobber redzone 0xab->0x%p\n\n", p);
-   validate_slab_cache(kmalloc_caches[type][9]);
-}
-#else
-#ifdef CONFIG_SYSFS
-static void resiliency_test(void) {};
-#endif
-#endif /* SLUB_RESILIENCY_TEST */
-
 #ifdef CONFIG_SYSFS
 enum slab_stat_type {
SL_ALL, /* All slabs */
@@ -5819,7 +5756,6 @@ static int __init slab_sysfs_init(void)
}
 
mutex_unlock(_mutex);
-   resiliency_test();
return 0;
 }
 
-- 
2.17.1