@@ -284,7 +284,7 @@ static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */
284284static wait_queue_head_t * barrier_cbs_wq ; /* Coordinate barrier testing. */
285285static DECLARE_WAIT_QUEUE_HEAD (barrier_wq );
286286
287- static bool rcu_fwd_cb_nodelay ; /* Short rcu_torture_delay() delays. */
287+ static atomic_t rcu_fwd_cb_nodelay ; /* Short rcu_torture_delay() delays. */
288288
289289/*
290290 * Allocate an element from the rcu_tortures pool.
@@ -387,7 +387,7 @@ rcu_read_delay(struct torture_random_state *rrsp, struct rt_read_seg *rtrsp)
387387 * period, and we want a long delay occasionally to trigger
388388 * force_quiescent_state. */
389389
390- if (!READ_ONCE ( rcu_fwd_cb_nodelay ) &&
390+ if (!atomic_read ( & rcu_fwd_cb_nodelay ) &&
391391 !(torture_random (rrsp ) % (nrealreaders * 2000 * longdelay_ms ))) {
392392 started = cur_ops -> get_gp_seq ();
393393 ts = rcu_trace_clock_local ();
@@ -674,6 +674,7 @@ static struct rcu_torture_ops srcu_ops = {
674674 .call = srcu_torture_call ,
675675 .cb_barrier = srcu_torture_barrier ,
676676 .stats = srcu_torture_stats ,
677+ .cbflood_max = 50000 ,
677678 .irq_capable = 1 ,
678679 .no_pi_lock = IS_ENABLED (CONFIG_TINY_SRCU ),
679680 .name = "srcu"
@@ -708,6 +709,7 @@ static struct rcu_torture_ops srcud_ops = {
708709 .call = srcu_torture_call ,
709710 .cb_barrier = srcu_torture_barrier ,
710711 .stats = srcu_torture_stats ,
712+ .cbflood_max = 50000 ,
711713 .irq_capable = 1 ,
712714 .no_pi_lock = IS_ENABLED (CONFIG_TINY_SRCU ),
713715 .name = "srcud"
@@ -997,7 +999,7 @@ static int rcu_torture_boost(void *arg)
997999 goto checkwait ;
9981000
9991001 /* Wait for the next test interval. */
1000- oldstarttime = boost_starttime ;
1002+ oldstarttime = READ_ONCE ( boost_starttime ) ;
10011003 while (time_before (jiffies , oldstarttime )) {
10021004 schedule_timeout_interruptible (oldstarttime - jiffies );
10031005 if (stutter_wait ("rcu_torture_boost" ))
@@ -1041,10 +1043,11 @@ static int rcu_torture_boost(void *arg)
10411043 * interval. Besides, we are running at RT priority,
10421044 * so delays should be relatively rare.
10431045 */
1044- while (oldstarttime == boost_starttime && !kthread_should_stop ()) {
1046+ while (oldstarttime == READ_ONCE ( boost_starttime ) && !kthread_should_stop ()) {
10451047 if (mutex_trylock (& boost_mutex )) {
10461048 if (oldstarttime == boost_starttime ) {
1047- boost_starttime = jiffies + test_boost_interval * HZ ;
1049+ WRITE_ONCE (boost_starttime ,
1050+ jiffies + test_boost_interval * HZ );
10481051 n_rcu_torture_boosts ++ ;
10491052 }
10501053 mutex_unlock (& boost_mutex );
@@ -1276,7 +1279,7 @@ rcu_torture_writer(void *arg)
12761279 boot_ended = rcu_inkernel_boot_has_ended ();
12771280 stutter_waited = stutter_wait ("rcu_torture_writer" );
12781281 if (stutter_waited &&
1279- !READ_ONCE ( rcu_fwd_cb_nodelay ) &&
1282+ !atomic_read ( & rcu_fwd_cb_nodelay ) &&
12801283 !cur_ops -> slow_gps &&
12811284 !torture_must_stop () &&
12821285 boot_ended )
@@ -2180,7 +2183,6 @@ static void rcu_torture_fwd_cb_hist(struct rcu_fwd *rfp)
21802183 for (i = ARRAY_SIZE (rfp -> n_launders_hist ) - 1 ; i > 0 ; i -- )
21812184 if (rfp -> n_launders_hist [i ].n_launders > 0 )
21822185 break ;
2183- mutex_lock (& rcu_fwd_mutex ); // Serialize histograms.
21842186 pr_alert ("%s: Callback-invocation histogram %d (duration %lu jiffies):" ,
21852187 __func__ , rfp -> rcu_fwd_id , jiffies - rfp -> rcu_fwd_startat );
21862188 gps_old = rfp -> rcu_launder_gp_seq_start ;
@@ -2193,7 +2195,6 @@ static void rcu_torture_fwd_cb_hist(struct rcu_fwd *rfp)
21932195 gps_old = gps ;
21942196 }
21952197 pr_cont ("\n" );
2196- mutex_unlock (& rcu_fwd_mutex );
21972198}
21982199
21992200/* Callback function for continuous-flood RCU callbacks. */
@@ -2281,6 +2282,7 @@ static void rcu_torture_fwd_prog_nr(struct rcu_fwd *rfp,
22812282 unsigned long stopat ;
22822283 static DEFINE_TORTURE_RANDOM (trs );
22832284
2285+ pr_alert ("%s: Starting forward-progress test %d\n" , __func__ , rfp -> rcu_fwd_id );
22842286 if (!cur_ops -> sync )
22852287 return ; // Cannot do need_resched() forward progress testing without ->sync.
22862288 if (cur_ops -> call && cur_ops -> cb_barrier ) {
@@ -2289,7 +2291,7 @@ static void rcu_torture_fwd_prog_nr(struct rcu_fwd *rfp,
22892291 }
22902292
22912293 /* Tight loop containing cond_resched(). */
2292- WRITE_ONCE ( rcu_fwd_cb_nodelay , true );
2294+ atomic_inc ( & rcu_fwd_cb_nodelay );
22932295 cur_ops -> sync (); /* Later readers see above write. */
22942296 if (selfpropcb ) {
22952297 WRITE_ONCE (fcs .stop , 0 );
@@ -2325,6 +2327,7 @@ static void rcu_torture_fwd_prog_nr(struct rcu_fwd *rfp,
23252327 if (selfpropcb ) {
23262328 WRITE_ONCE (fcs .stop , 1 );
23272329 cur_ops -> sync (); /* Wait for running CB to complete. */
2330+ pr_alert ("%s: Waiting for CBs: %pS() %d\n" , __func__ , cur_ops -> cb_barrier , rfp -> rcu_fwd_id );
23282331 cur_ops -> cb_barrier (); /* Wait for queued callbacks. */
23292332 }
23302333
@@ -2333,7 +2336,7 @@ static void rcu_torture_fwd_prog_nr(struct rcu_fwd *rfp,
23332336 destroy_rcu_head_on_stack (& fcs .rh );
23342337 }
23352338 schedule_timeout_uninterruptible (HZ / 10 ); /* Let kthreads recover. */
2336- WRITE_ONCE ( rcu_fwd_cb_nodelay , false );
2339+ atomic_dec ( & rcu_fwd_cb_nodelay );
23372340}
23382341
23392342/* Carry out call_rcu() forward-progress testing. */
@@ -2353,13 +2356,14 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp)
23532356 unsigned long stopat ;
23542357 unsigned long stoppedat ;
23552358
2359+ pr_alert ("%s: Starting forward-progress test %d\n" , __func__ , rfp -> rcu_fwd_id );
23562360 if (READ_ONCE (rcu_fwd_emergency_stop ))
23572361 return ; /* Get out of the way quickly, no GP wait! */
23582362 if (!cur_ops -> call )
23592363 return ; /* Can't do call_rcu() fwd prog without ->call. */
23602364
23612365 /* Loop continuously posting RCU callbacks. */
2362- WRITE_ONCE ( rcu_fwd_cb_nodelay , true );
2366+ atomic_inc ( & rcu_fwd_cb_nodelay );
23632367 cur_ops -> sync (); /* Later readers see above write. */
23642368 WRITE_ONCE (rfp -> rcu_fwd_startat , jiffies );
23652369 stopat = rfp -> rcu_fwd_startat + MAX_FWD_CB_JIFFIES ;
@@ -2414,6 +2418,7 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp)
24142418 n_launders_cb_snap = READ_ONCE (rfp -> n_launders_cb );
24152419 cver = READ_ONCE (rcu_torture_current_version ) - cver ;
24162420 gps = rcutorture_seq_diff (cur_ops -> get_gp_seq (), gps );
2421+ pr_alert ("%s: Waiting for CBs: %pS() %d\n" , __func__ , cur_ops -> cb_barrier , rfp -> rcu_fwd_id );
24172422 cur_ops -> cb_barrier (); /* Wait for callbacks to be invoked. */
24182423 (void )rcu_torture_fwd_prog_cbfree (rfp );
24192424
@@ -2427,11 +2432,13 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp)
24272432 n_launders , n_launders_sa ,
24282433 n_max_gps , n_max_cbs , cver , gps );
24292434 atomic_long_add (n_max_cbs , & rcu_fwd_max_cbs );
2435+ mutex_lock (& rcu_fwd_mutex ); // Serialize histograms.
24302436 rcu_torture_fwd_cb_hist (rfp );
2437+ mutex_unlock (& rcu_fwd_mutex );
24312438 }
24322439 schedule_timeout_uninterruptible (HZ ); /* Let CBs drain. */
24332440 tick_dep_clear_task (current , TICK_DEP_BIT_RCU );
2434- WRITE_ONCE ( rcu_fwd_cb_nodelay , false );
2441+ atomic_dec ( & rcu_fwd_cb_nodelay );
24352442}
24362443
24372444
@@ -2511,7 +2518,7 @@ static int rcu_torture_fwd_prog(void *args)
25112518 firsttime = false;
25122519 WRITE_ONCE (rcu_fwd_seq , rcu_fwd_seq + 1 );
25132520 } else {
2514- while (READ_ONCE (rcu_fwd_seq ) == oldseq )
2521+ while (READ_ONCE (rcu_fwd_seq ) == oldseq && ! torture_must_stop () )
25152522 schedule_timeout_interruptible (1 );
25162523 oldseq = READ_ONCE (rcu_fwd_seq );
25172524 }
@@ -2905,8 +2912,10 @@ rcu_torture_cleanup(void)
29052912 int i ;
29062913
29072914 if (torture_cleanup_begin ()) {
2908- if (cur_ops -> cb_barrier != NULL )
2915+ if (cur_ops -> cb_barrier != NULL ) {
2916+ pr_info ("%s: Invoking %pS().\n" , __func__ , cur_ops -> cb_barrier );
29092917 cur_ops -> cb_barrier ();
2918+ }
29102919 return ;
29112920 }
29122921 if (!cur_ops ) {
@@ -2961,8 +2970,10 @@ rcu_torture_cleanup(void)
29612970 * Wait for all RCU callbacks to fire, then do torture-type-specific
29622971 * cleanup operations.
29632972 */
2964- if (cur_ops -> cb_barrier != NULL )
2973+ if (cur_ops -> cb_barrier != NULL ) {
2974+ pr_info ("%s: Invoking %pS().\n" , __func__ , cur_ops -> cb_barrier );
29652975 cur_ops -> cb_barrier ();
2976+ }
29662977 if (cur_ops -> cleanup != NULL )
29672978 cur_ops -> cleanup ();
29682979
0 commit comments