@@ -357,7 +357,9 @@ struct rcu_torture_ops {
357357 bool (* poll_gp_state_exp )(unsigned long oldstate );
358358 void (* cond_sync_exp )(unsigned long oldstate );
359359 void (* cond_sync_exp_full )(struct rcu_gp_oldstate * rgosp );
360+ unsigned long (* get_comp_state )(void );
360361 void (* get_comp_state_full )(struct rcu_gp_oldstate * rgosp );
362+ bool (* same_gp_state )(unsigned long oldstate1 , unsigned long oldstate2 );
361363 bool (* same_gp_state_full )(struct rcu_gp_oldstate * rgosp1 , struct rcu_gp_oldstate * rgosp2 );
362364 unsigned long (* get_gp_state )(void );
363365 void (* get_gp_state_full )(struct rcu_gp_oldstate * rgosp );
@@ -537,7 +539,9 @@ static struct rcu_torture_ops rcu_ops = {
537539 .deferred_free = rcu_torture_deferred_free ,
538540 .sync = synchronize_rcu ,
539541 .exp_sync = synchronize_rcu_expedited ,
542+ .same_gp_state = same_state_synchronize_rcu ,
540543 .same_gp_state_full = same_state_synchronize_rcu_full ,
544+ .get_comp_state = get_completed_synchronize_rcu ,
541545 .get_comp_state_full = get_completed_synchronize_rcu_full ,
542546 .get_gp_state = get_state_synchronize_rcu ,
543547 .get_gp_state_full = get_state_synchronize_rcu_full ,
@@ -1262,7 +1266,8 @@ static void rcu_torture_write_types(void)
12621266 } else if (gp_normal && !cur_ops -> deferred_free ) {
12631267 pr_alert ("%s: gp_normal without primitives.\n" , __func__ );
12641268 }
1265- if (gp_poll1 && cur_ops -> start_gp_poll && cur_ops -> poll_gp_state ) {
1269+ if (gp_poll1 && cur_ops -> get_comp_state && cur_ops -> same_gp_state &&
1270+ cur_ops -> start_gp_poll && cur_ops -> poll_gp_state ) {
12661271 synctype [nsynctypes ++ ] = RTWS_POLL_GET ;
12671272 pr_info ("%s: Testing polling GPs.\n" , __func__ );
12681273 } else if (gp_poll && (!cur_ops -> start_gp_poll || !cur_ops -> poll_gp_state )) {
@@ -1344,6 +1349,7 @@ rcu_torture_writer(void *arg)
13441349 struct rcu_gp_oldstate cookie_full ;
13451350 int expediting = 0 ;
13461351 unsigned long gp_snap ;
1352+ unsigned long gp_snap1 ;
13471353 struct rcu_gp_oldstate gp_snap_full ;
13481354 struct rcu_gp_oldstate gp_snap1_full ;
13491355 int i ;
@@ -1354,6 +1360,7 @@ rcu_torture_writer(void *arg)
13541360 struct rcu_torture * old_rp ;
13551361 static DEFINE_TORTURE_RANDOM (rand );
13561362 bool stutter_waited ;
1363+ unsigned long ulo [NUM_ACTIVE_RCU_POLL_OLDSTATE ];
13571364
13581365 VERBOSE_TOROUT_STRING ("rcu_torture_writer task started" );
13591366 if (!can_expedite )
@@ -1470,11 +1477,22 @@ rcu_torture_writer(void *arg)
14701477 break ;
14711478 case RTWS_POLL_GET :
14721479 rcu_torture_writer_state = RTWS_POLL_GET ;
1480+ for (i = 0 ; i < ARRAY_SIZE (ulo ); i ++ )
1481+ ulo [i ] = cur_ops -> get_comp_state ();
14731482 gp_snap = cur_ops -> start_gp_poll ();
14741483 rcu_torture_writer_state = RTWS_POLL_WAIT ;
1475- while (!cur_ops -> poll_gp_state (gp_snap ))
1484+ while (!cur_ops -> poll_gp_state (gp_snap )) {
1485+ gp_snap1 = cur_ops -> get_gp_state ();
1486+ for (i = 0 ; i < ARRAY_SIZE (ulo ); i ++ )
1487+ if (cur_ops -> poll_gp_state (ulo [i ]) ||
1488+ cur_ops -> same_gp_state (ulo [i ], gp_snap1 )) {
1489+ ulo [i ] = gp_snap1 ;
1490+ break ;
1491+ }
1492+ WARN_ON_ONCE (i >= ARRAY_SIZE (ulo ));
14761493 torture_hrtimeout_jiffies (torture_random (& rand ) % 16 ,
14771494 & rand );
1495+ }
14781496 rcu_torture_pipe_update (old_rp );
14791497 break ;
14801498 case RTWS_POLL_GET_FULL :
0 commit comments