Skip to content

Commit 8d71351

Browse files
ZqiangNeeraj Upadhyay (AMD)
authored andcommitted
rcutorture: Fix rcutorture_one_extend_check() splat in RT kernels
For built with CONFIG_PREEMPT_RT=y kernels, running rcutorture tests resulted in the following splat: [ 68.797425] rcutorture_one_extend_check during change: Current 0x1 To add 0x1 To remove 0x0 preempt_count() 0x0 [ 68.797533] WARNING: CPU: 2 PID: 512 at kernel/rcu/rcutorture.c:1993 rcutorture_one_extend_check+0x419/0x560 [rcutorture] [ 68.797601] Call Trace: [ 68.797602] <TASK> [ 68.797619] ? lockdep_softirqs_off+0xa5/0x160 [ 68.797631] rcutorture_one_extend+0x18e/0xcc0 [rcutorture 2466dbd2ff34dbaa36049cb323a80c3306ac997c] [ 68.797646] ? local_clock+0x19/0x40 [ 68.797659] rcu_torture_one_read+0xf0/0x280 [rcutorture 2466dbd2ff34dbaa36049cb323a80c3306ac997c] [ 68.797678] ? __pfx_rcu_torture_one_read+0x10/0x10 [rcutorture 2466dbd2ff34dbaa36049cb323a80c3306ac997c] [ 68.797804] ? __pfx_rcu_torture_timer+0x10/0x10 [rcutorture 2466dbd2ff34dbaa36049cb323a80c3306ac997c] [ 68.797815] rcu-torture: rcu_torture_reader task started [ 68.797824] rcu-torture: Creating rcu_torture_reader task [ 68.797824] rcu_torture_reader+0x238/0x580 [rcutorture 2466dbd2ff34dbaa36049cb323a80c3306ac997c] [ 68.797836] ? kvm_sched_clock_read+0x15/0x30 Disable BH does not change the SOFTIRQ corresponding bits in preempt_count() for RT kernels, this commit therefore use softirq_count() to check the if BH is disabled. Reviewed-by: Paul E. McKenney <[email protected]> Signed-off-by: Zqiang <[email protected]> Signed-off-by: Joel Fernandes <[email protected]> Signed-off-by: Neeraj Upadhyay (AMD) <[email protected]>
1 parent 5f2417b commit 8d71351

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

kernel/rcu/rcutorture.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ rcu_read_delay(struct torture_random_state *rrsp, struct rt_read_seg *rtrsp)
471471
!(torture_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) {
472472
started = cur_ops->get_gp_seq();
473473
ts = rcu_trace_clock_local();
474-
if (preempt_count() & (SOFTIRQ_MASK | HARDIRQ_MASK))
474+
if ((preempt_count() & HARDIRQ_MASK) || softirq_count())
475475
longdelay_ms = 5; /* Avoid triggering BH limits. */
476476
mdelay(longdelay_ms);
477477
rtrsp->rt_delay_ms = longdelay_ms;
@@ -2001,7 +2001,7 @@ static void rcutorture_one_extend_check(char *s, int curstate, int new, int old)
20012001
return;
20022002

20032003
WARN_ONCE((curstate & (RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH)) &&
2004-
!(preempt_count() & SOFTIRQ_MASK), ROEC_ARGS);
2004+
!softirq_count(), ROEC_ARGS);
20052005
WARN_ONCE((curstate & (RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED)) &&
20062006
!(preempt_count() & PREEMPT_MASK), ROEC_ARGS);
20072007
WARN_ONCE(cur_ops->readlock_nesting &&
@@ -2015,7 +2015,7 @@ static void rcutorture_one_extend_check(char *s, int curstate, int new, int old)
20152015

20162016
WARN_ONCE(cur_ops->extendables &&
20172017
!(curstate & (RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH)) &&
2018-
(preempt_count() & SOFTIRQ_MASK), ROEC_ARGS);
2018+
softirq_count(), ROEC_ARGS);
20192019

20202020
/*
20212021
* non-preemptible RCU in a preemptible kernel uses preempt_disable()
@@ -2036,6 +2036,9 @@ static void rcutorture_one_extend_check(char *s, int curstate, int new, int old)
20362036
if (!IS_ENABLED(CONFIG_PREEMPT_RCU))
20372037
mask |= RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
20382038

2039+
if (IS_ENABLED(CONFIG_PREEMPT_RT) && softirq_count())
2040+
mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
2041+
20392042
WARN_ONCE(cur_ops->readlock_nesting && !(curstate & mask) &&
20402043
cur_ops->readlock_nesting() > 0, ROEC_ARGS);
20412044
}

0 commit comments

Comments
 (0)