rcutorture: Make rcu_torture_fakewriter() use blocking wait primitives

Full testing of the new SRCU polling API requires that the fake
writers also use it in order to test concurrent calls to all of the API
members, especially start_poll_synchronize_srcu().  This commit makes
rcu_torture_fakewriter() use all available blocking grace-period-wait
primitives available from the RCU flavor under test.

Link: https://lore.kernel.org/rcu/20201112201547.GF3365678@moria.home.lan/
Reported-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
Paul E. McKenney 2020-11-16 17:10:39 -08:00
parent 18fbf307b7
commit 682189a3f8
1 changed files with 32 additions and 8 deletions

View File

@ -1289,6 +1289,8 @@ rcu_torture_writer(void *arg)
static int static int
rcu_torture_fakewriter(void *arg) rcu_torture_fakewriter(void *arg)
{ {
unsigned long gp_snap;
int i;
DEFINE_TORTURE_RANDOM(rand); DEFINE_TORTURE_RANDOM(rand);
VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task started"); VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task started");
@ -1300,15 +1302,37 @@ rcu_torture_fakewriter(void *arg)
if (cur_ops->cb_barrier != NULL && if (cur_ops->cb_barrier != NULL &&
torture_random(&rand) % (nfakewriters * 8) == 0) { torture_random(&rand) % (nfakewriters * 8) == 0) {
cur_ops->cb_barrier(); cur_ops->cb_barrier();
} else if (gp_normal == gp_exp) { } else {
if (cur_ops->sync && torture_random(&rand) & 0x80) switch (synctype[torture_random(&rand) % nsynctypes]) {
cur_ops->sync(); case RTWS_DEF_FREE:
else if (cur_ops->exp_sync) break;
case RTWS_EXP_SYNC:
cur_ops->exp_sync(); cur_ops->exp_sync();
} else if (gp_normal && cur_ops->sync) { break;
case RTWS_COND_GET:
gp_snap = cur_ops->get_gp_state();
i = torture_random(&rand) % 16;
if (i != 0)
schedule_timeout_interruptible(i);
udelay(torture_random(&rand) % 1000);
cur_ops->cond_sync(gp_snap);
break;
case RTWS_POLL_GET:
gp_snap = cur_ops->start_gp_poll();
while (!cur_ops->poll_gp_state(gp_snap)) {
i = torture_random(&rand) % 16;
if (i != 0)
schedule_timeout_interruptible(i);
udelay(torture_random(&rand) % 1000);
}
break;
case RTWS_SYNC:
cur_ops->sync(); cur_ops->sync();
} else if (cur_ops->exp_sync) { break;
cur_ops->exp_sync(); default:
WARN_ON_ONCE(1);
break;
}
} }
stutter_wait("rcu_torture_fakewriter"); stutter_wait("rcu_torture_fakewriter");
} while (!torture_must_stop()); } while (!torture_must_stop());