@@ -357,7 +357,9 @@ struct rcu_torture_ops {
357
357
bool (* poll_gp_state_exp )(unsigned long oldstate );
358
358
void (* cond_sync_exp )(unsigned long oldstate );
359
359
void (* cond_sync_exp_full )(struct rcu_gp_oldstate * rgosp );
360
+ unsigned long (* get_comp_state )(void );
360
361
void (* get_comp_state_full )(struct rcu_gp_oldstate * rgosp );
362
+ bool (* same_gp_state )(unsigned long oldstate1 , unsigned long oldstate2 );
361
363
bool (* same_gp_state_full )(struct rcu_gp_oldstate * rgosp1 , struct rcu_gp_oldstate * rgosp2 );
362
364
unsigned long (* get_gp_state )(void );
363
365
void (* get_gp_state_full )(struct rcu_gp_oldstate * rgosp );
@@ -537,7 +539,9 @@ static struct rcu_torture_ops rcu_ops = {
537
539
.deferred_free = rcu_torture_deferred_free ,
538
540
.sync = synchronize_rcu ,
539
541
.exp_sync = synchronize_rcu_expedited ,
542
+ .same_gp_state = same_state_synchronize_rcu ,
540
543
.same_gp_state_full = same_state_synchronize_rcu_full ,
544
+ .get_comp_state = get_completed_synchronize_rcu ,
541
545
.get_comp_state_full = get_completed_synchronize_rcu_full ,
542
546
.get_gp_state = get_state_synchronize_rcu ,
543
547
.get_gp_state_full = get_state_synchronize_rcu_full ,
@@ -1262,7 +1266,8 @@ static void rcu_torture_write_types(void)
1262
1266
} else if (gp_normal && !cur_ops -> deferred_free ) {
1263
1267
pr_alert ("%s: gp_normal without primitives.\n" , __func__ );
1264
1268
}
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 ) {
1266
1271
synctype [nsynctypes ++ ] = RTWS_POLL_GET ;
1267
1272
pr_info ("%s: Testing polling GPs.\n" , __func__ );
1268
1273
} else if (gp_poll && (!cur_ops -> start_gp_poll || !cur_ops -> poll_gp_state )) {
@@ -1344,6 +1349,7 @@ rcu_torture_writer(void *arg)
1344
1349
struct rcu_gp_oldstate cookie_full ;
1345
1350
int expediting = 0 ;
1346
1351
unsigned long gp_snap ;
1352
+ unsigned long gp_snap1 ;
1347
1353
struct rcu_gp_oldstate gp_snap_full ;
1348
1354
struct rcu_gp_oldstate gp_snap1_full ;
1349
1355
int i ;
@@ -1354,6 +1360,7 @@ rcu_torture_writer(void *arg)
1354
1360
struct rcu_torture * old_rp ;
1355
1361
static DEFINE_TORTURE_RANDOM (rand );
1356
1362
bool stutter_waited ;
1363
+ unsigned long ulo [NUM_ACTIVE_RCU_POLL_OLDSTATE ];
1357
1364
1358
1365
VERBOSE_TOROUT_STRING ("rcu_torture_writer task started" );
1359
1366
if (!can_expedite )
@@ -1470,11 +1477,22 @@ rcu_torture_writer(void *arg)
1470
1477
break ;
1471
1478
case RTWS_POLL_GET :
1472
1479
rcu_torture_writer_state = RTWS_POLL_GET ;
1480
+ for (i = 0 ; i < ARRAY_SIZE (ulo ); i ++ )
1481
+ ulo [i ] = cur_ops -> get_comp_state ();
1473
1482
gp_snap = cur_ops -> start_gp_poll ();
1474
1483
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 ));
1476
1493
torture_hrtimeout_jiffies (torture_random (& rand ) % 16 ,
1477
1494
& rand );
1495
+ }
1478
1496
rcu_torture_pipe_update (old_rp );
1479
1497
break ;
1480
1498
case RTWS_POLL_GET_FULL :
0 commit comments