@@ -115,6 +115,7 @@ torture_param(int, stall_cpu_holdoff, 10, "Time to wait before starting stall (s
115115torture_param (bool , stall_no_softlockup , false, "Avoid softlockup warning during cpu stall." );
116116torture_param (int , stall_cpu_irqsoff , 0 , "Disable interrupts while stalling." );
117117torture_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." );
118119torture_param (int , stall_gp_kthread , 0 , "Grace-period kthread stall duration (s)." );
119120torture_param (int , stat_interval , 60 , "Number of seconds between stats printk()s" );
120121torture_param (int , stutter , 5 , "Number of seconds to run/halt test" );
@@ -1393,7 +1394,8 @@ rcu_torture_writer(void *arg)
13931394
13941395 // If a new stall test is added, this must be adjusted.
13951396 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 );
13971399 VERBOSE_TOROUT_STRING ("rcu_torture_writer task started" );
13981400 if (!can_expedite )
13991401 pr_alert ("%s" TORTURE_FLAG
@@ -2391,7 +2393,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
23912393 "test_boost=%d/%d test_boost_interval=%d "
23922394 "test_boost_duration=%d shutdown_secs=%d "
23932395 "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 "
23952397 "n_barrier_cbs=%d "
23962398 "onoff_interval=%d onoff_holdoff=%d "
23972399 "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)
24032405 test_boost , cur_ops -> can_boost ,
24042406 test_boost_interval , test_boost_duration , shutdown_secs ,
24052407 stall_cpu , stall_cpu_holdoff , stall_cpu_irqsoff ,
2406- stall_cpu_block ,
2408+ stall_cpu_block , stall_cpu_repeat ,
24072409 n_barrier_cbs ,
24082410 onoff_interval , onoff_holdoff ,
24092411 read_exit_delay , read_exit_burst ,
@@ -2481,19 +2483,11 @@ static struct notifier_block rcu_torture_stall_block = {
24812483 * induces a CPU stall for the time specified by stall_cpu. If a new
24822484 * stall test is added, stallsdone in rcu_torture_writer() must be adjusted.
24832485 */
2484- static int rcu_torture_stall ( void * args )
2486+ static void rcu_torture_stall_one ( int rep , int irqsoff )
24852487{
24862488 int idx ;
2487- int ret ;
24882489 unsigned long stop_at ;
24892490
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- }
24972491 if (stall_cpu_holdoff > 0 ) {
24982492 VERBOSE_TOROUT_STRING ("rcu_torture_stall begin holdoff" );
24992493 schedule_timeout_interruptible (stall_cpu_holdoff * HZ );
@@ -2513,12 +2507,12 @@ static int rcu_torture_stall(void *args)
25132507 stop_at = ktime_get_seconds () + stall_cpu ;
25142508 /* RCU CPU stall is expected behavior in following code. */
25152509 idx = cur_ops -> readlock ();
2516- if (stall_cpu_irqsoff )
2510+ if (irqsoff )
25172511 local_irq_disable ();
25182512 else if (!stall_cpu_block )
25192513 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 ());
25222516 while (ULONG_CMP_LT ((unsigned long )ktime_get_seconds (), stop_at ) &&
25232517 !kthread_should_stop ())
25242518 if (stall_cpu_block ) {
@@ -2530,12 +2524,42 @@ static int rcu_torture_stall(void *args)
25302524 } else if (stall_no_softlockup ) {
25312525 touch_softlockup_watchdog ();
25322526 }
2533- if (stall_cpu_irqsoff )
2527+ if (irqsoff )
25342528 local_irq_enable ();
25352529 else if (!stall_cpu_block )
25362530 preempt_enable ();
25372531 cur_ops -> readunlock (idx );
25382532 }
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+ }
25392563 pr_alert ("%s end.\n" , __func__ );
25402564 if (rcu_cpu_stall_notifiers && !ret ) {
25412565 ret = rcu_stall_chain_notifier_unregister (& rcu_torture_stall_block );
0 commit comments