[PATCH for-next v3 9/9] slub_kunit: extend the test for kfree_rcu_nolock()
From: Harry Yoo (Oracle)
Date: Mon Jun 15 2026 - 07:08:23 EST
When slub_kunit is not built-in, call kfree_rcu() and kfree_rcu_nolock()
to test kfree_rcu_nolock() in slub_kunit.
Rename the test case as the test covers more _nolock() APIs.
Signed-off-by: Harry Yoo (Oracle) <harry@xxxxxxxxxx>
---
lib/tests/slub_kunit.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/lib/tests/slub_kunit.c b/lib/tests/slub_kunit.c
index 01d808cb77fa..6ed4de88bf0b 100644
--- a/lib/tests/slub_kunit.c
+++ b/lib/tests/slub_kunit.c
@@ -162,7 +162,10 @@ static void test_kmalloc_redzone_access(struct kunit *test)
}
struct test_kfree_rcu_struct {
- struct rcu_head rcu;
+ union {
+ struct rcu_head rcu;
+ struct kfree_rcu_head krcu;
+ };
};
static void test_kfree_rcu(struct kunit *test)
@@ -294,10 +297,10 @@ static void test_krealloc_redzone_zeroing(struct kunit *test)
}
#if defined(CONFIG_PERF_EVENTS) || (defined(CONFIG_KPROBES) && defined(CONFIG_SMP))
-#define SLUB_KUNIT_TEST_KMALLOC_KFREE_NOLOCK
+#define SLUB_KUNIT_TEST_KMALLOC_NOLOCK_AND_FRIENDS
#define NR_ITERATIONS 1000
#define NR_OBJECTS 1000
-static void *objects[NR_OBJECTS];
+static struct test_kfree_rcu_struct *objects[NR_OBJECTS];
struct test_nolock_context {
struct kunit *test;
@@ -336,19 +339,24 @@ static struct perf_event_attr sw_attr = {
static void test_nolock(struct test_nolock_context *ctx)
{
- void *objp;
+ struct test_kfree_rcu_struct *objp;
gfp_t gfp;
+ bool can_use_kfree_rcu = !IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST);
/* __GFP_ACCOUNT to test kmalloc_nolock() in alloc_slab_obj_exts() */
gfp = (ctx->callback_count % 2) ? 0 : __GFP_ACCOUNT;
- objp = kmalloc_nolock(64, gfp, NUMA_NO_NODE);
+ objp = kmalloc_nolock(sizeof(*objp), gfp, NUMA_NO_NODE);
if (objp)
ctx->alloc_ok++;
else
ctx->alloc_fail++;
- kfree_nolock(objp);
+ if (can_use_kfree_rcu && (ctx->callback_count % 2))
+ kfree_rcu_nolock(objp, krcu);
+ else
+ kfree_nolock(objp);
+
ctx->callback_count++;
}
@@ -432,12 +440,13 @@ static bool register_slab_kprobes(struct test_nolock_context *ctx) { return fals
static void unregister_slab_kprobes(struct test_nolock_context *ctx) { }
#endif
-static void test_kmalloc_kfree_nolock(struct kunit *test)
+static void test_kmalloc_nolock_and_friends(struct kunit *test)
{
int i, j;
struct test_nolock_context perf_ctx = { .test = test };
struct test_nolock_context kprobe_ctx = { .test = test };
bool alloc_fail = false;
+ bool can_use_kfree_rcu = !IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST);
bool perf_events_enabled;
bool slab_kprobes_enabled;
@@ -455,7 +464,7 @@ static void test_kmalloc_kfree_nolock(struct kunit *test)
for (j = 0; j < NR_OBJECTS; j++) {
gfp_t gfp = (i % 2) ? GFP_KERNEL : GFP_KERNEL_ACCOUNT;
- objects[j] = kmalloc(64, gfp);
+ objects[j] = kmalloc_obj(*objects[j], gfp);
if (!objects[j]) {
j--;
while (j >= 0)
@@ -464,8 +473,13 @@ static void test_kmalloc_kfree_nolock(struct kunit *test)
goto cleanup;
}
}
- for (j = 0; j < NR_OBJECTS; j++)
- kfree(objects[j]);
+
+ for (j = 0; j < NR_OBJECTS; j++) {
+ if (can_use_kfree_rcu && (i % 2))
+ kfree_rcu(objects[j], rcu);
+ else
+ kfree(objects[j]);
+ }
}
cleanup:
@@ -504,8 +518,8 @@ static struct kunit_case test_cases[] = {
KUNIT_CASE(test_kfree_rcu_wq_destroy),
KUNIT_CASE(test_leak_destroy),
KUNIT_CASE(test_krealloc_redzone_zeroing),
-#ifdef SLUB_KUNIT_TEST_KMALLOC_KFREE_NOLOCK
- KUNIT_CASE_SLOW(test_kmalloc_kfree_nolock),
+#ifdef SLUB_KUNIT_TEST_KMALLOC_NOLOCK_AND_FRIENDS
+ KUNIT_CASE_SLOW(test_kmalloc_nolock_and_friends),
#endif
{}
};
--
2.53.0