Re: [PATCH 0/5] rcu: Record callback enqueue stacks and add torture tests
From: KunWu Chan
Date: Sun Nov 08 2026 - 21:41:23 EST
On Sat, Nov 7, 2026 at 12:20 PM Zqiang <qiang.zhang@xxxxxxxxx> wrote:
>
> >
> > On Fri, Nov 06, 2026 at 01:49:04PM -0500, Joel Fernandes wrote:
> >
> > >
> > > On 11/6/2026 9:39 AM, Kunwu Chan wrote:
> > > This series adds KASAN auxiliary stack recording for RCU Tasks
> > > callbacks, rcutorture coverage for duplicate-callback detection,
> > > and KASAN aux-stack verification tests across RCU and SRCU flavors.
> > >
> > > This series is based on [1]. For testing, I also applied Joel
> > > Fernandes' fix for debugobjects tracking of barrier callbacks
> > > [2], which is needed for the barrier tests.
> > >
> > > The changes:
> > > - Record the enqueueing stack in call_rcu_tasks_generic().
> > > - Enable duplicate-callback testing for the "tasks" and
> > > "tasks-tracing" torture types.
> > > - Add a KASAN aux-stack verification test module with a Kconfig
> > > choice for each supported flavor.
> > > - Add one rcutorture scenario per flavor for the verification
> > > test.
> > >
> > > Tested on x86_64:
> > >
> > > - TASKS01, TASKS02, TASKS03, TRACE01, and TRACE02 completed
> > > 3-minute runs successfully.
> > >
> > > - With CONFIG_DEBUG_OBJECTS_RCU_HEAD=y and
> > > rcutorture.object_debug=1, duplicate-callback detection was
> > > triggered as expected for both torture types.
> > >
> > > - TRACE01 was run for 1 minute with
> > > CONFIG_DEBUG_OBJECTS_RCU_HEAD=y and
> > > rcutorture.object_debug=1. The test detected both duplicate
> > > callback heads through the SRCU enqueue path:
> > > [ 0.405836] rcutorture: WARN: Duplicate call_tasks-tracing() test starting.
> > > [ 0.405852] ODEBUG: activate active (active state 1) object: 0000000020df980d object type: rcu_head hint: 0x0
> > > [ 0.734724] rcu: __call_srcu(): Duplicate call_srcu() CB 0000000020df980d->rcu_torture_leak_cb+0x0/0x10()
> > > [ 0.734780] ODEBUG: activate active (active state 1) object: 000000006634e8c9 object type: rcu_head hint: 0x0
> > > [ 0.776688] rcu: __call_srcu(): Duplicate call_srcu() CB 000000006634e8c9->rcu_torture_leak_cb+0x0/0x10()
> > > [ 0.779126] rcutorture: WARN: Duplicate call_tasks-tracing() test complete.
> > > [ 65.411342] tasks-tracing-torture:--- End of test: SUCCESS: ...
> > >
> > > Both duplicate callback heads (the stack-allocated rh2 and
> > > the kmalloc-allocated rhp) were rejected and neither was invoked.
> > >
> > > - With CONFIG_DEBUG_OBJECTS_RCU_HEAD=y,
> > > object_debug=1, and n_barrier_cbs=4, the TASKS01 barrier
> > > test completed 630/630 rounds without barrier errors.
> > > The only debugobjects warnings were the four intentional
> > > warnings from the duplicate-callback test at startup.
> > >
> > > - All five aux-stack scenarios (TASKSKASAN01, TREEKASAN01,
> > > SRCUKASAN01, TINYKASAN01, and SRCUTINYKASAN01) produced the
> > > expected KASAN use-after-free reports. Each report's
> > > "Last potentially related work creation" entry showed the
> > > expected enqueue helper:
> > >
> > > ===== TASKSKASAN01 =====
> > > [ 1.244567] BUG: KASAN: slab-use-after-free in aux_test_init+0x8d/0xb0
> > > [ 1.244707] Last potentially related work creation:
> > > [ 1.244716] aux_test_call_rcu_tasks.constprop.0+0xc/0x20
> > >
> > > ===== TREEKASAN01 =====
> > > [ 0.670399] BUG: KASAN: slab-use-after-free in aux_test_init+0x8d/0xb0
> > > [ 0.670561] Last potentially related work creation:
> > > [ 0.670571] aux_test_call_rcu_tree.constprop.0+0xc/0x20
> > >
> > > ===== SRCUKASAN01 =====
> > > [ 0.658679] BUG: KASAN: slab-use-after-free in aux_test_init+0x94/0xc0
> > > [ 0.658919] Last potentially related work creation:
> > > [ 0.658932] aux_test_call_srcu.constprop.0+0x16/0x30
> > >
> > > ===== TINYKASAN01 =====
> > > [ 0.951503] BUG: KASAN: slab-use-after-free in aux_test_init+0x8d/0xb0
> > > [ 0.951641] Last potentially related work creation:
> > > [ 0.951650] aux_test_call_rcu_tiny.constprop.0+0xc/0x20
> > >
> > > ===== SRCUTINYKASAN01 =====
> > > [ 1.009005] BUG: KASAN: slab-use-after-free in aux_test_init+0x94/0xc0
> > > [ 1.009141] Last potentially related work creation:
> > > [ 1.009150] aux_test_call_srcu.constprop.0+0x16/0x30
> > >
> > > I'm not feeling very excited about adding more configs just for KASAN. That
> > > sounds like a maintenance burden. I believe Paul already has KASAN testing in
> > > his scripts. Is it possible to activate this testing only when those are enabled?
> > >
> > The usual way that I do KASAN testing is with the --kasan argument
> > to kvm.sh. I use --kconfig and --bootargs to specify further testing,
> > usually as another option in torture.sh. This causes the testing to
> > be carried out as a matter of course.
> >
> > One good thing is that the Kconfig choice in patch 4/5 is automated so
> > that RCU_KASAN_AUX_TEST causes the right testing to happen depending on
> > what is configured.
> >
> > Is it possible to drive this from --kasan and the rcutorture.object_debug
> > kernel boot parameter or something similar? Or is there a better way
> > to make the overall testing happen?
>
> Hello, Kunwu
>
> Perhaps we can simplify this testing, similar to object_debug testing.
> double-free also should output stack (I did not actually test the
> modifications below) which record by kasan_record_aux_stack():
>
>
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index 968343be4e0d..93b30bf90cc9 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -120,6 +120,7 @@ torture_param(bool, nmi_calls, true, "Exercise ->call() from NMI on nmi_capable
> torture_param(int, nreaders, -1, "Number of RCU reader threads");
> torture_param(bool, nwriters, 1, "Number of RCU writer threads (0 or 1)");
> torture_param(int, object_debug, 0, "Enable debug-object double call_rcu() testing");
> +torture_param(int, kasan_debug, 0, "Enable call_rcu() kasan testing");
> torture_param(int, onoff_holdoff, 0, "Time after boot before CPU hotplugs (s)");
> torture_param(int, onoff_interval, 0, "Time between CPU hotplugs (jiffies), 0=disable");
> torture_param(bool, gpwrap_lag, true, "Enable grace-period wrap lag testing");
> @@ -4632,6 +4633,25 @@ static void rcu_test_debug_objects(void)
> kfree(rhp);
> }
>
> +static void rcu_free_cb(struct rcu_head *rhp)
> +{
> + kfree(rhp);
> +}
> +
> +static void rcu_test_kasan(void)
> +{
> + if (!IS_ENABLED(CONFIG_KASAN_GENERIC) ||
> + !cur_ops->call || !cur_ops->cb_barrier)
> + return;
> +
> + struct rcu_head *rhp = kmalloc_obj(*rhp);
> + if (rhp) {
> + cur_ops->call(rhp, rcu_free_cb);
> + cur_ops->cb_barrier();
> + }
> + kfree(rhp);
> +}
> +
> static void rcutorture_sync(void)
> {
> static unsigned long n;
> @@ -5191,6 +5211,9 @@ rcu_torture_init(void)
> if (object_debug)
> rcu_test_debug_objects();
>
> + if (kasan_debug)
> + rcu_test_kasan();
> +
> if (cur_ops->gp_slow_register && !WARN_ON_ONCE(!cur_ops->gp_slow_unregister))
> cur_ops->gp_slow_register(&rcu_fwd_cb_nodelay);
>
>
>
> Thanks
> Zqiang
>
Thanks Joel, Paul, and Zqiang.
I agree that we should avoid extra KASAN-specific configs and integrate the
testing into the existing KASAN/torture workflow. I'll look into how
best to do that.
Zqiang, thanks for the code suggestion.
I'll look more closely at which callback paths it covers and how the
intentional
KASAN report should be handled by the torture scripts. The important part is
to make sure that "Last potentially related work creation" points to
the expected
callback enqueue helper, rather than just triggering a KASAN report.
I'll consider all these points for the next revision.
Thanks,
Kunwu
>
> >
> > Thanx, Paul
> >