On 19 October 2026 03:36:44 BST, [email protected] wrote: >From: Fu Wenxin <[email protected]> > >Commit e4ed20c1603c ("rcutorture: Exercise DEFINE_STATIC_SRCU_FAST() and >init_srcu_struct_fast()") split SRCU torture initialization into two >helpers: srcu_torture_init(), which now only points srcu_ctlp at the >static srcu_ctl/srcu_ctlf/srcu_ctlfud structures, and the new >srcud_torture_init(), which calls init_srcu_struct(&srcu_ctld) for the >dynamically allocated srcu_ctld. > >That commit updated srcud_ops to use srcud_torture_init(), but left >busted_srcud_ops pairing .init = srcu_torture_init (static srcu_ctl) with >.cleanup = srcu_torture_cleanup (which unconditionally calls >cleanup_srcu_struct(&srcu_ctld)). As a result srcu_ctld is never >initialized when running torture_type=busted_srcud, yet it is torn down >at module unload. > >cleanup_srcu_struct() then dereferences ssp->srcu_sup, which is still >NULL for the zero-initialized srcu_ctld, and faults on the ->lock field >accessed by raw_spin_lock_irq_rcu_node(): > > Unable to handle kernel paging request at virtual address dfff80000000001b > ... > el1_abort -> do_translation_fault -> do_bad_area -> die_kernel_fault > >(The fault address is the KASAN shadow of NULL + offsetof(srcu_usage, >lock) == 0xd8.) > >This is trivially reproducible: > > modprobe rcutorture torture_type=busted_srcud > sleep 45 > rmmod rcutorture # panic here > >Fix it by making busted_srcud_ops initialize the same srcu_ctld that its >cleanup handler tears down, matching srcud_ops. > >Fixes: e4ed20c1603c ("rcutorture: Exercise DEFINE_STATIC_SRCU_FAST() and >init_srcu_struct_fast()")
Nice catch! I reproduced this bug on my PowerPC host: Reviewed-by: Bradley Morgan <[email protected]> Tested-by: Bradley Morgan <[email protected]> # Power10 >Signed-off-by: Fu Wenxin <[email protected]> >--- > kernel/rcu/rcutorture.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c >index 8a9282a0245cc..7cc78da1356f9 100644 >--- a/kernel/rcu/rcutorture.c >+++ b/kernel/rcu/rcutorture.c >@@ -991,7 +991,7 @@ static struct rcu_torture_ops srcud_ops = { > /* As above, but broken due to inappropriate reader extension. */ > static struct rcu_torture_ops busted_srcud_ops = { > .ttype = SRCU_FLAVOR, >- .init = srcu_torture_init, >+ .init = srcud_torture_init, > .cleanup = srcu_torture_cleanup, > .readlock = srcu_torture_read_lock, > .read_delay = rcu_read_delay, > --- Thanks! "I'm not a very positive person" - Linus torvalds

