From: "Harry Yoo (Oracle)" <harry@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>,
Vlastimil Babka <vbabka@kernel.org>
Cc: Christoph Lameter <cl@gentwo.org>,
David Rientjes <rientjes@google.com>,
Roman Gushchin <roman.gushchin@linux.dev>,
Hao Li <hao.li@linux.dev>, Alexei Starovoitov <ast@kernel.org>,
Uladzislau Rezki <urezki@gmail.com>,
"Paul E . McKenney" <paulmck@kernel.org>,
Frederic Weisbecker <frederic@kernel.org>,
Neeraj Upadhyay <neeraj.upadhyay@kernel.org>,
Joel Fernandes <joelagnelf@nvidia.com>,
Josh Triplett <josh@joshtriplett.org>,
Boqun Feng <boqun@kernel.org>, Zqiang <qiang.zhang@linux.dev>,
Steven Rostedt <rostedt@goodmis.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Lai Jiangshan <jiangshanlai@gmail.com>,
rcu@vger.kernel.org, linux-mm@kvack.org
Subject: [PATCH 8/8] lib/tests/slub_kunit: add a test case for kfree_rcu_nolock()
Date: Thu, 16 Apr 2026 18:10:22 +0900 [thread overview]
Message-ID: <20260416091022.36823-9-harry@kernel.org> (raw)
In-Reply-To: <20260416091022.36823-1-harry@kernel.org>
Similar to test_kmalloc_kfree_nolock, add a test that allocates objects
via kmalloc_nolock() and frees them via kfree_rcu_nolock() in a perf
overflow handler (NMI or hardirq depending on the arch), while the main
loop allocates and frees objects via kmalloc() and kfree_rcu().
Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
---
lib/tests/slub_kunit.c | 73 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/lib/tests/slub_kunit.c b/lib/tests/slub_kunit.c
index fa6d31dbca16..f8d979912246 100644
--- a/lib/tests/slub_kunit.c
+++ b/lib/tests/slub_kunit.c
@@ -367,6 +367,78 @@ static void test_kmalloc_kfree_nolock(struct kunit *test)
kfree(objects[j]);
}
+cleanup:
+ perf_event_disable(ctx.event);
+ perf_event_release_kernel(ctx.event);
+
+ kunit_info(test, "callback_count: %d, alloc_ok: %d, alloc_fail: %d\n",
+ ctx.callback_count, ctx.alloc_ok, ctx.alloc_fail);
+
+ if (alloc_fail)
+ kunit_skip(test, "Allocation failed");
+ KUNIT_EXPECT_EQ(test, 0, slab_errors);
+}
+
+struct dummy_struct {
+ struct rcu_ptr rcu;
+};
+
+static void overflow_handler_test_kfree_rcu_nolock(struct perf_event *event,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ struct dummy_struct *dummy;
+ gfp_t gfp;
+ struct test_nolock_context *ctx = event->overflow_handler_context;
+
+ /* __GFP_ACCOUNT to test kmalloc_nolock() in alloc_slab_obj_exts() */
+ gfp = (ctx->callback_count % 2) ? 0 : __GFP_ACCOUNT;
+ dummy = kmalloc_nolock(sizeof(*dummy), gfp, NUMA_NO_NODE);
+
+ if (dummy) {
+ ctx->alloc_ok++;
+ kfree_rcu_nolock(dummy, rcu);
+ } else {
+ ctx->alloc_fail++;
+ }
+ ctx->callback_count++;
+}
+
+static void test_kfree_rcu_nolock(struct kunit *test)
+{
+ int i, j;
+ struct test_nolock_context ctx = { .test = test };
+ struct perf_event *event;
+ bool alloc_fail = false;
+ struct dummy_struct *dummy;
+
+ if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST))
+ kunit_skip(test, "can't do kfree_rcu_nolock() when test is built-in");
+
+ event = perf_event_create_kernel_counter(&hw_attr, -1, current,
+ overflow_handler_test_kfree_rcu_nolock,
+ &ctx);
+ if (IS_ERR(event))
+ kunit_skip(test, "Failed to create perf event");
+ ctx.event = event;
+ perf_event_enable(ctx.event);
+ for (i = 0; i < NR_ITERATIONS; i++) {
+ for (j = 0; j < NR_OBJECTS; j++) {
+ gfp_t gfp = (i % 2) ? GFP_KERNEL : GFP_KERNEL_ACCOUNT;
+
+ objects[j] = kmalloc(sizeof(*dummy), gfp);
+ if (!objects[j]) {
+ j--;
+ while (j >= 0)
+ kfree(objects[j--]);
+ alloc_fail = true;
+ goto cleanup;
+ }
+ }
+ for (j = 0; j < NR_OBJECTS; j++)
+ kfree_rcu((struct dummy_struct *)objects[j], rcu);
+ }
+
cleanup:
perf_event_disable(ctx.event);
perf_event_release_kernel(ctx.event);
@@ -406,6 +478,7 @@ static struct kunit_case test_cases[] = {
KUNIT_CASE(test_krealloc_redzone_zeroing),
#ifdef CONFIG_PERF_EVENTS
KUNIT_CASE_SLOW(test_kmalloc_kfree_nolock),
+ KUNIT_CASE_SLOW(test_kfree_rcu_nolock),
#endif
{}
};
--
2.43.0
next prev parent reply other threads:[~2026-04-16 9:10 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-16 9:10 [RFC PATCH v2 0/8] kvfree_rcu() improvements Harry Yoo (Oracle)
2026-04-16 9:10 ` [PATCH 1/8] mm/slab: introduce k[v]free_rcu() with struct rcu_ptr Harry Yoo (Oracle)
2026-04-22 14:41 ` Vlastimil Babka (SUSE)
2026-04-23 1:36 ` Harry Yoo (Oracle)
2026-04-16 9:10 ` [PATCH 2/8] fs/dcache: use rcu_ptr instead of rcu_head for external names Harry Yoo (Oracle)
2026-04-21 20:21 ` Al Viro
2026-04-22 1:16 ` Harry Yoo (Oracle)
2026-04-16 9:10 ` [PATCH 3/8] mm/slab: move kfree_rcu_cpu[_work] definitions Harry Yoo (Oracle)
2026-04-16 9:10 ` [PATCH 4/8] mm/slab: introduce kfree_rcu_nolock() Harry Yoo (Oracle)
2026-04-21 22:46 ` Alexei Starovoitov
2026-04-21 23:10 ` Paul E. McKenney
2026-04-21 23:14 ` Alexei Starovoitov
2026-04-22 3:02 ` Harry Yoo (Oracle)
2026-04-22 14:42 ` Uladzislau Rezki
2026-04-23 1:08 ` Harry Yoo (Oracle)
2026-04-23 1:56 ` Harry Yoo (Oracle)
2026-04-27 18:08 ` Vlastimil Babka (SUSE)
2026-04-27 18:51 ` Paul E. McKenney
2026-04-23 2:14 ` Harry Yoo (Oracle)
2026-04-23 4:23 ` Harry Yoo (Oracle)
2026-04-23 11:35 ` Uladzislau Rezki
2026-04-28 13:12 ` Harry Yoo (Oracle)
2026-04-30 12:10 ` Uladzislau Rezki
2026-04-27 13:08 ` Vlastimil Babka (SUSE)
2026-04-16 9:10 ` [PATCH 5/8] mm/slab: make kfree_rcu_nolock() work with sheaves Harry Yoo (Oracle)
2026-04-27 13:32 ` Vlastimil Babka (SUSE)
2026-04-27 13:53 ` Vlastimil Babka (SUSE)
2026-04-27 14:45 ` Alexei Starovoitov
2026-04-27 15:08 ` Vlastimil Babka (SUSE)
2026-04-27 15:11 ` Alexei Starovoitov
2026-04-16 9:10 ` [PATCH 6/8] mm/slab: wrap rcu sheaf handling with ifdef Harry Yoo (Oracle)
2026-04-27 15:47 ` Vlastimil Babka (SUSE)
2026-04-16 9:10 ` [PATCH 7/8] mm/slab: introduce deferred submission of rcu sheaves Harry Yoo (Oracle)
2026-04-21 22:51 ` Alexei Starovoitov
2026-04-22 3:11 ` Harry Yoo (Oracle)
2026-04-27 15:55 ` Vlastimil Babka (SUSE)
2026-04-16 9:10 ` Harry Yoo (Oracle) [this message]
2026-04-22 14:30 ` [RFC PATCH v2 0/8] kvfree_rcu() improvements Vlastimil Babka (SUSE)
2026-04-22 22:41 ` Paul E. McKenney
2026-04-23 1:31 ` Harry Yoo (Oracle)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260416091022.36823-9-harry@kernel.org \
--to=harry@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=ast@kernel.org \
--cc=boqun@kernel.org \
--cc=cl@gentwo.org \
--cc=frederic@kernel.org \
--cc=hao.li@linux.dev \
--cc=jiangshanlai@gmail.com \
--cc=joelagnelf@nvidia.com \
--cc=josh@joshtriplett.org \
--cc=linux-mm@kvack.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=neeraj.upadhyay@kernel.org \
--cc=paulmck@kernel.org \
--cc=qiang.zhang@linux.dev \
--cc=rcu@vger.kernel.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
--cc=rostedt@goodmis.org \
--cc=urezki@gmail.com \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.