@@ -357,6 +357,8 @@ 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+ void (* get_comp_state_full )(struct rcu_gp_oldstate * rgosp );
361+ bool (* same_gp_state_full )(struct rcu_gp_oldstate * rgosp1 , struct rcu_gp_oldstate * rgosp2 );
360362 unsigned long (* get_gp_state )(void );
361363 void (* get_gp_state_full )(struct rcu_gp_oldstate * rgosp );
362364 unsigned long (* get_gp_completed )(void );
@@ -535,6 +537,8 @@ static struct rcu_torture_ops rcu_ops = {
535537 .deferred_free = rcu_torture_deferred_free ,
536538 .sync = synchronize_rcu ,
537539 .exp_sync = synchronize_rcu_expedited ,
540+ .same_gp_state_full = same_state_synchronize_rcu_full ,
541+ .get_comp_state_full = get_completed_synchronize_rcu_full ,
538542 .get_gp_state = get_state_synchronize_rcu ,
539543 .get_gp_state_full = get_state_synchronize_rcu_full ,
540544 .get_gp_completed = get_completed_synchronize_rcu ,
@@ -1264,7 +1268,8 @@ static void rcu_torture_write_types(void)
12641268 } else if (gp_poll && (!cur_ops -> start_gp_poll || !cur_ops -> poll_gp_state )) {
12651269 pr_alert ("%s: gp_poll without primitives.\n" , __func__ );
12661270 }
1267- if (gp_poll_full1 && cur_ops -> start_gp_poll_full && cur_ops -> poll_gp_state_full ) {
1271+ if (gp_poll_full1 && cur_ops -> get_comp_state_full && cur_ops -> same_gp_state_full
1272+ && cur_ops -> start_gp_poll_full && cur_ops -> poll_gp_state_full ) {
12681273 synctype [nsynctypes ++ ] = RTWS_POLL_GET_FULL ;
12691274 pr_info ("%s: Testing polling full-state GPs.\n" , __func__ );
12701275 } else if (gp_poll_full && (!cur_ops -> start_gp_poll_full || !cur_ops -> poll_gp_state_full )) {
@@ -1340,9 +1345,11 @@ rcu_torture_writer(void *arg)
13401345 int expediting = 0 ;
13411346 unsigned long gp_snap ;
13421347 struct rcu_gp_oldstate gp_snap_full ;
1348+ struct rcu_gp_oldstate gp_snap1_full ;
13431349 int i ;
13441350 int idx ;
13451351 int oldnice = task_nice (current );
1352+ struct rcu_gp_oldstate rgo [NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE ];
13461353 struct rcu_torture * rp ;
13471354 struct rcu_torture * old_rp ;
13481355 static DEFINE_TORTURE_RANDOM (rand );
@@ -1472,11 +1479,23 @@ rcu_torture_writer(void *arg)
14721479 break ;
14731480 case RTWS_POLL_GET_FULL :
14741481 rcu_torture_writer_state = RTWS_POLL_GET_FULL ;
1482+ for (i = 0 ; i < ARRAY_SIZE (rgo ); i ++ )
1483+ cur_ops -> get_comp_state_full (& rgo [i ]);
14751484 cur_ops -> start_gp_poll_full (& gp_snap_full );
14761485 rcu_torture_writer_state = RTWS_POLL_WAIT_FULL ;
1477- while (!cur_ops -> poll_gp_state_full (& gp_snap_full ))
1486+ while (!cur_ops -> poll_gp_state_full (& gp_snap_full )) {
1487+ cur_ops -> get_gp_state_full (& gp_snap1_full );
1488+ for (i = 0 ; i < ARRAY_SIZE (rgo ); i ++ )
1489+ if (cur_ops -> poll_gp_state_full (& rgo [i ]) ||
1490+ cur_ops -> same_gp_state_full (& rgo [i ],
1491+ & gp_snap1_full )) {
1492+ rgo [i ] = gp_snap1_full ;
1493+ break ;
1494+ }
1495+ WARN_ON_ONCE (i >= ARRAY_SIZE (rgo ));
14781496 torture_hrtimeout_jiffies (torture_random (& rand ) % 16 ,
14791497 & rand );
1498+ }
14801499 rcu_torture_pipe_update (old_rp );
14811500 break ;
14821501 case RTWS_POLL_GET_EXP :
0 commit comments