Re: [PATCH] rcutorture: Add fqs_holdoff check before the fqs_task is created

From: Z qiang
Date: Fri Nov 03 2023 - 11:50:29 EST


>
> For rcutorture tests that support fqs operations and set fqs_duration
> greater than zero, the fqs_task kthread will be created. but if the
> fqs_holdoff is not set, the default value is zero, this cause fqs_task
> enter a long-term busy loop and won't voluntarily give up the CPU until
> stopped by kthread_stop(). this commit therefore add for fqs_holdoff check
> before the fqs_task is created, make sure the fqs_task is created when
> the fqs_holdoff is also greater than zero.
>
> Signed-off-by: Zqiang <qiang.zhang1211@xxxxxxxxx>
>


if not apply this patch, will trigger rcu stall for built with
PREEMPT_RCU=n kernels.

runqemu kvm nographic slirp qemuparams="-smp 2 -m 1024"
bootparams="rcutorture.fqs_duration=4" -d

[ 31.071252] rcu: INFO: rcu_sched self-detected stall on CPU
[ 31.071264] rcu: 0-....: (25999 ticks this GP)
idle=a10c/1/0x4000000000000000 softirq=3064/3065 fqs=2038552
[ 31.071273] rcu: hardirqs softirqs csw/system
[ 31.071277] rcu: number: 0 212 0
[ 31.071281] rcu: cputime: 166 1 12830 ==> 12999(ms)
[ 31.071286] rcu: (t=26000 jiffies g=1373 q=13803 ncpus=2)
[ 31.071292] CPU: 0 PID: 48 Comm: rcu_torture_fqs Tainted: G
L 6.6.0-rc2-rt4zqiang #54
[ 31.071299] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
[ 31.071303] RIP: 0010:_raw_spin_unlock_irqrestore+0x47/0x60
[ 31.071314] Code: 08 e8 cd c6 92 fe 4c 89 e7 e8 b5 2d 93 fe 81 e3
00 02 00 00 75 1d 9c 58 f6 c4 02 75 1d 48 85 db 74 01 fb 65 ff 0d 51
86 98 66 <5b> b
[ 31.071319] RSP: 0018:ffff888004237e38 EFLAGS: 00000246
[ 31.071326] RAX: 0000000000000046 RBX: 0000000000000200 RCX: ffffffff981ab987
[ 31.071331] RDX: 0000000000000003 RSI: dffffc0000000000 RDI: ffffffff99883445
[ 31.071335] RBP: ffff888004237e48 R08: 0000000000000000 R09: 0000000000000000
[ 31.071339] R10: fffffbfff3672d80 R11: ffffffff9b396c07 R12: ffffffff9ac02518
[ 31.071344] R13: 0000000000000246 R14: 0000000000000000 R15: 0000000000000000
[ 31.071348] FS: 0000000000000000(0000) GS:ffff888035e00000(0000)
knlGS:0000000000000000
[ 31.071355] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 31.071359] CR2: 0000561df3203100 CR3: 0000000024a78000 CR4: 00000000001506f0
[ 31.071364] Call Trace:
[ 31.071367] <IRQ>
[ 31.071372] ? show_regs+0x66/0x70
[ 31.071379] ? dump_cpu_task+0x68/0x70
[ 31.071387] ? rcu_dump_cpu_stacks+0x179/0x2b0
[ 31.071396] ? rcu_sched_clock_irq+0xb5c/0x11a0
[ 31.071402] ? irqtime_account_process_tick+0x158/0x210
[ 31.071411] ? update_process_times+0x6e/0xa0
[ 31.071418] ? tick_sched_timer+0x185/0x1d0
[ 31.071425] ? __pfx_tick_sched_timer+0x10/0x10
[ 31.071431] ? __hrtimer_run_queues+0x403/0x640
[ 31.071438] ? hrtimer_interrupt+0x77/0x350
[ 31.071445] ? __pfx___hrtimer_run_queues+0x10/0x10
[ 31.071451] ? kvm_clock_get_cycles+0x1c/0x30
[ 31.071457] ? ktime_get_update_offsets_now+0x102/0x200
[ 31.071464] ? hrtimer_interrupt+0x1ae/0x350
[ 31.071473] ? __sysvec_apic_timer_interrupt+0xaa/0x240
[ 31.071480] ? sysvec_apic_timer_interrupt+0x75/0x90
[ 31.071487] </IRQ>
[ 31.071491] <TASK>
[ 31.071494] ? asm_sysvec_apic_timer_interrupt+0x1f/0x30
[ 31.071502] ? lockdep_hardirqs_on_prepare+0x17/0x230
[ 31.071510] ? _raw_spin_unlock_irqrestore+0x55/0x60
[ 31.071516] ? _raw_spin_unlock_irqrestore+0x47/0x60
[ 31.071524] swake_up_one+0x47/0x60
[ 31.071531] rcu_gp_kthread_wake+0x63/0x90
[ 31.071537] rcu_force_quiescent_state+0xfb/0x160
[ 31.071544] rcu_torture_fqs+0xc4/0x160
[ 31.071552] ? __pfx_rcu_torture_fqs+0x10/0x10
[ 31.071559] kthread+0x197/0x1d0
[ 31.071565] ? kthread+0x107/0x1d0
[ 31.071571] ? __pfx_kthread+0x10/0x10
[ 31.071577] ret_from_fork+0x40/0x60
[ 31.071583] ? __pfx_kthread+0x10/0x10
[ 31.071590] ret_from_fork_asm+0x1b/0x30
[ 31.071599] </TASK>

Thanks
Zqiang

> ---
> kernel/rcu/rcutorture.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index 83999e57b3ea..9f0e6c1cad44 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -3886,7 +3886,9 @@ rcu_torture_init(void)
> }
> if (fqs_duration < 0)
> fqs_duration = 0;
> - if (fqs_duration) {
> + if (fqs_holdoff < 0)
> + fqs_holdoff = 0;
> + if (fqs_duration && fqs_holdoff) {
> /* Create the fqs thread */
> firsterr = torture_create_kthread(rcu_torture_fqs, NULL,
> fqs_task);
> --
> 2.17.1
>