@@ -115,6 +115,7 @@ torture_param(int, stall_cpu_holdoff, 10, "Time to wait before starting stall (s
115
115
torture_param (bool , stall_no_softlockup , false, "Avoid softlockup warning during cpu stall." );
116
116
torture_param (int , stall_cpu_irqsoff , 0 , "Disable interrupts while stalling." );
117
117
torture_param (int , stall_cpu_block , 0 , "Sleep while stalling." );
118
+ torture_param (int , stall_cpu_repeat , 0 , "Number of additional stalls after the first one." );
118
119
torture_param (int , stall_gp_kthread , 0 , "Grace-period kthread stall duration (s)." );
119
120
torture_param (int , stat_interval , 60 , "Number of seconds between stats printk()s" );
120
121
torture_param (int , stutter , 5 , "Number of seconds to run/halt test" );
@@ -1393,7 +1394,8 @@ rcu_torture_writer(void *arg)
1393
1394
1394
1395
// If a new stall test is added, this must be adjusted.
1395
1396
if (stall_cpu_holdoff + stall_gp_kthread + stall_cpu )
1396
- stallsdone += (stall_cpu_holdoff + stall_gp_kthread + stall_cpu + 60 ) * HZ ;
1397
+ stallsdone += (stall_cpu_holdoff + stall_gp_kthread + stall_cpu + 60 ) *
1398
+ HZ * (stall_cpu_repeat + 1 );
1397
1399
VERBOSE_TOROUT_STRING ("rcu_torture_writer task started" );
1398
1400
if (!can_expedite )
1399
1401
pr_alert ("%s" TORTURE_FLAG
@@ -2391,7 +2393,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
2391
2393
"test_boost=%d/%d test_boost_interval=%d "
2392
2394
"test_boost_duration=%d shutdown_secs=%d "
2393
2395
"stall_cpu=%d stall_cpu_holdoff=%d stall_cpu_irqsoff=%d "
2394
- "stall_cpu_block=%d "
2396
+ "stall_cpu_block=%d stall_cpu_repeat=%d "
2395
2397
"n_barrier_cbs=%d "
2396
2398
"onoff_interval=%d onoff_holdoff=%d "
2397
2399
"read_exit_delay=%d read_exit_burst=%d "
@@ -2403,7 +2405,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
2403
2405
test_boost , cur_ops -> can_boost ,
2404
2406
test_boost_interval , test_boost_duration , shutdown_secs ,
2405
2407
stall_cpu , stall_cpu_holdoff , stall_cpu_irqsoff ,
2406
- stall_cpu_block ,
2408
+ stall_cpu_block , stall_cpu_repeat ,
2407
2409
n_barrier_cbs ,
2408
2410
onoff_interval , onoff_holdoff ,
2409
2411
read_exit_delay , read_exit_burst ,
@@ -2481,19 +2483,11 @@ static struct notifier_block rcu_torture_stall_block = {
2481
2483
* induces a CPU stall for the time specified by stall_cpu. If a new
2482
2484
* stall test is added, stallsdone in rcu_torture_writer() must be adjusted.
2483
2485
*/
2484
- static int rcu_torture_stall ( void * args )
2486
+ static void rcu_torture_stall_one ( int rep , int irqsoff )
2485
2487
{
2486
2488
int idx ;
2487
- int ret ;
2488
2489
unsigned long stop_at ;
2489
2490
2490
- VERBOSE_TOROUT_STRING ("rcu_torture_stall task started" );
2491
- if (rcu_cpu_stall_notifiers ) {
2492
- ret = rcu_stall_chain_notifier_register (& rcu_torture_stall_block );
2493
- if (ret )
2494
- pr_info ("%s: rcu_stall_chain_notifier_register() returned %d, %sexpected.\n" ,
2495
- __func__ , ret , !IS_ENABLED (CONFIG_RCU_STALL_COMMON ) ? "un" : "" );
2496
- }
2497
2491
if (stall_cpu_holdoff > 0 ) {
2498
2492
VERBOSE_TOROUT_STRING ("rcu_torture_stall begin holdoff" );
2499
2493
schedule_timeout_interruptible (stall_cpu_holdoff * HZ );
@@ -2513,12 +2507,12 @@ static int rcu_torture_stall(void *args)
2513
2507
stop_at = ktime_get_seconds () + stall_cpu ;
2514
2508
/* RCU CPU stall is expected behavior in following code. */
2515
2509
idx = cur_ops -> readlock ();
2516
- if (stall_cpu_irqsoff )
2510
+ if (irqsoff )
2517
2511
local_irq_disable ();
2518
2512
else if (!stall_cpu_block )
2519
2513
preempt_disable ();
2520
- pr_alert ("%s start on CPU %d.\n" ,
2521
- __func__ , raw_smp_processor_id ());
2514
+ pr_alert ("%s start stall episode %d on CPU %d.\n" ,
2515
+ __func__ , rep + 1 , raw_smp_processor_id ());
2522
2516
while (ULONG_CMP_LT ((unsigned long )ktime_get_seconds (), stop_at ) &&
2523
2517
!kthread_should_stop ())
2524
2518
if (stall_cpu_block ) {
@@ -2530,12 +2524,42 @@ static int rcu_torture_stall(void *args)
2530
2524
} else if (stall_no_softlockup ) {
2531
2525
touch_softlockup_watchdog ();
2532
2526
}
2533
- if (stall_cpu_irqsoff )
2527
+ if (irqsoff )
2534
2528
local_irq_enable ();
2535
2529
else if (!stall_cpu_block )
2536
2530
preempt_enable ();
2537
2531
cur_ops -> readunlock (idx );
2538
2532
}
2533
+ }
2534
+
2535
+ /*
2536
+ * CPU-stall kthread. Invokes rcu_torture_stall_one() once, and then as many
2537
+ * additional times as specified by the stall_cpu_repeat module parameter.
2538
+ * Note that stall_cpu_irqsoff is ignored on the second and subsequent
2539
+ * stall.
2540
+ */
2541
+ static int rcu_torture_stall (void * args )
2542
+ {
2543
+ int i ;
2544
+ int repeat = stall_cpu_repeat ;
2545
+ int ret ;
2546
+
2547
+ VERBOSE_TOROUT_STRING ("rcu_torture_stall task started" );
2548
+ if (repeat < 0 ) {
2549
+ repeat = 0 ;
2550
+ WARN_ON_ONCE (IS_BUILTIN (CONFIG_RCU_TORTURE_TEST ));
2551
+ }
2552
+ if (rcu_cpu_stall_notifiers ) {
2553
+ ret = rcu_stall_chain_notifier_register (& rcu_torture_stall_block );
2554
+ if (ret )
2555
+ pr_info ("%s: rcu_stall_chain_notifier_register() returned %d, %sexpected.\n" ,
2556
+ __func__ , ret , !IS_ENABLED (CONFIG_RCU_STALL_COMMON ) ? "un" : "" );
2557
+ }
2558
+ for (i = 0 ; i <= repeat ; i ++ ) {
2559
+ if (kthread_should_stop ())
2560
+ break ;
2561
+ rcu_torture_stall_one (i , i == 0 ? stall_cpu_irqsoff : 0 );
2562
+ }
2539
2563
pr_alert ("%s end.\n" , __func__ );
2540
2564
if (rcu_cpu_stall_notifiers && !ret ) {
2541
2565
ret = rcu_stall_chain_notifier_unregister (& rcu_torture_stall_block );
0 commit comments