Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kunit, slub: add test_kfree_rcu() and test_leak_destroy()

Add a test that will create cache, allocate one object, kfree_rcu() it
and attempt to destroy it. As long as the usage of kvfree_rcu_barrier()
in kmem_cache_destroy() works correctly, there should be no warnings in
dmesg and the test should pass.

Additionally add a test_leak_destroy() test that leaks an object on
purpose and verifies that kmem_cache_destroy() catches it.

Signed-off-by: Vlastimil Babka <vbabka@suse.cz>

+31
+31
lib/slub_kunit.c
··· 5 5 #include <linux/slab.h> 6 6 #include <linux/module.h> 7 7 #include <linux/kernel.h> 8 + #include <linux/rcupdate.h> 8 9 #include "../mm/slab.h" 9 10 10 11 static struct kunit_resource resource; ··· 158 157 kmem_cache_destroy(s); 159 158 } 160 159 160 + struct test_kfree_rcu_struct { 161 + struct rcu_head rcu; 162 + }; 163 + 164 + static void test_kfree_rcu(struct kunit *test) 165 + { 166 + struct kmem_cache *s = test_kmem_cache_create("TestSlub_kfree_rcu", 167 + sizeof(struct test_kfree_rcu_struct), 168 + SLAB_NO_MERGE); 169 + struct test_kfree_rcu_struct *p = kmem_cache_alloc(s, GFP_KERNEL); 170 + 171 + kfree_rcu(p, rcu); 172 + kmem_cache_destroy(s); 173 + 174 + KUNIT_EXPECT_EQ(test, 0, slab_errors); 175 + } 176 + 177 + static void test_leak_destroy(struct kunit *test) 178 + { 179 + struct kmem_cache *s = test_kmem_cache_create("TestSlub_kfree_rcu", 180 + 64, SLAB_NO_MERGE); 181 + kmem_cache_alloc(s, GFP_KERNEL); 182 + 183 + kmem_cache_destroy(s); 184 + 185 + KUNIT_EXPECT_EQ(test, 1, slab_errors); 186 + } 187 + 161 188 static int test_init(struct kunit *test) 162 189 { 163 190 slab_errors = 0; ··· 206 177 207 178 KUNIT_CASE(test_clobber_redzone_free), 208 179 KUNIT_CASE(test_kmalloc_redzone_access), 180 + KUNIT_CASE(test_kfree_rcu), 181 + KUNIT_CASE(test_leak_destroy), 209 182 {} 210 183 }; 211 184