Commit a5c095e0 authored by Paul E. McKenney's avatar Paul E. McKenney

rcutorture: Abstract read-lock-held checks

This commit adds a (*readlock_held)() function pointer to the
rcu_torture_ops structure in order to make the rcu_torture_one_read()
function's rcu_dereference_check() lockdep expression more appropriate
for a given run.
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent e9b800db
...@@ -331,6 +331,7 @@ struct rcu_torture_ops { ...@@ -331,6 +331,7 @@ struct rcu_torture_ops {
void (*read_delay)(struct torture_random_state *rrsp, void (*read_delay)(struct torture_random_state *rrsp,
struct rt_read_seg *rtrsp); struct rt_read_seg *rtrsp);
void (*readunlock)(int idx); void (*readunlock)(int idx);
int (*readlock_held)(void);
unsigned long (*get_gp_seq)(void); unsigned long (*get_gp_seq)(void);
unsigned long (*gp_diff)(unsigned long new, unsigned long old); unsigned long (*gp_diff)(unsigned long new, unsigned long old);
void (*deferred_free)(struct rcu_torture *p); void (*deferred_free)(struct rcu_torture *p);
...@@ -359,6 +360,11 @@ static struct rcu_torture_ops *cur_ops; ...@@ -359,6 +360,11 @@ static struct rcu_torture_ops *cur_ops;
* Definitions for rcu torture testing. * Definitions for rcu torture testing.
*/ */
static int torture_readlock_not_held(void)
{
return rcu_read_lock_bh_held() || rcu_read_lock_sched_held();
}
static int rcu_torture_read_lock(void) __acquires(RCU) static int rcu_torture_read_lock(void) __acquires(RCU)
{ {
rcu_read_lock(); rcu_read_lock();
...@@ -488,6 +494,7 @@ static struct rcu_torture_ops rcu_ops = { ...@@ -488,6 +494,7 @@ static struct rcu_torture_ops rcu_ops = {
.readlock = rcu_torture_read_lock, .readlock = rcu_torture_read_lock,
.read_delay = rcu_read_delay, .read_delay = rcu_read_delay,
.readunlock = rcu_torture_read_unlock, .readunlock = rcu_torture_read_unlock,
.readlock_held = torture_readlock_not_held,
.get_gp_seq = rcu_get_gp_seq, .get_gp_seq = rcu_get_gp_seq,
.gp_diff = rcu_seq_diff, .gp_diff = rcu_seq_diff,
.deferred_free = rcu_torture_deferred_free, .deferred_free = rcu_torture_deferred_free,
...@@ -540,6 +547,7 @@ static struct rcu_torture_ops rcu_busted_ops = { ...@@ -540,6 +547,7 @@ static struct rcu_torture_ops rcu_busted_ops = {
.readlock = rcu_torture_read_lock, .readlock = rcu_torture_read_lock,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */ .read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = rcu_torture_read_unlock, .readunlock = rcu_torture_read_unlock,
.readlock_held = torture_readlock_not_held,
.get_gp_seq = rcu_no_completed, .get_gp_seq = rcu_no_completed,
.deferred_free = rcu_busted_torture_deferred_free, .deferred_free = rcu_busted_torture_deferred_free,
.sync = synchronize_rcu_busted, .sync = synchronize_rcu_busted,
...@@ -589,6 +597,11 @@ static void srcu_torture_read_unlock(int idx) __releases(srcu_ctlp) ...@@ -589,6 +597,11 @@ static void srcu_torture_read_unlock(int idx) __releases(srcu_ctlp)
srcu_read_unlock(srcu_ctlp, idx); srcu_read_unlock(srcu_ctlp, idx);
} }
static int torture_srcu_read_lock_held(void)
{
return srcu_read_lock_held(srcu_ctlp);
}
static unsigned long srcu_torture_completed(void) static unsigned long srcu_torture_completed(void)
{ {
return srcu_batches_completed(srcu_ctlp); return srcu_batches_completed(srcu_ctlp);
...@@ -646,6 +659,7 @@ static struct rcu_torture_ops srcu_ops = { ...@@ -646,6 +659,7 @@ static struct rcu_torture_ops srcu_ops = {
.readlock = srcu_torture_read_lock, .readlock = srcu_torture_read_lock,
.read_delay = srcu_read_delay, .read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock, .readunlock = srcu_torture_read_unlock,
.readlock_held = torture_srcu_read_lock_held,
.get_gp_seq = srcu_torture_completed, .get_gp_seq = srcu_torture_completed,
.deferred_free = srcu_torture_deferred_free, .deferred_free = srcu_torture_deferred_free,
.sync = srcu_torture_synchronize, .sync = srcu_torture_synchronize,
...@@ -681,6 +695,7 @@ static struct rcu_torture_ops srcud_ops = { ...@@ -681,6 +695,7 @@ static struct rcu_torture_ops srcud_ops = {
.readlock = srcu_torture_read_lock, .readlock = srcu_torture_read_lock,
.read_delay = srcu_read_delay, .read_delay = srcu_read_delay,
.readunlock = srcu_torture_read_unlock, .readunlock = srcu_torture_read_unlock,
.readlock_held = torture_srcu_read_lock_held,
.get_gp_seq = srcu_torture_completed, .get_gp_seq = srcu_torture_completed,
.deferred_free = srcu_torture_deferred_free, .deferred_free = srcu_torture_deferred_free,
.sync = srcu_torture_synchronize, .sync = srcu_torture_synchronize,
...@@ -700,6 +715,7 @@ static struct rcu_torture_ops busted_srcud_ops = { ...@@ -700,6 +715,7 @@ static struct rcu_torture_ops busted_srcud_ops = {
.readlock = srcu_torture_read_lock, .readlock = srcu_torture_read_lock,
.read_delay = rcu_read_delay, .read_delay = rcu_read_delay,
.readunlock = srcu_torture_read_unlock, .readunlock = srcu_torture_read_unlock,
.readlock_held = torture_srcu_read_lock_held,
.get_gp_seq = srcu_torture_completed, .get_gp_seq = srcu_torture_completed,
.deferred_free = srcu_torture_deferred_free, .deferred_free = srcu_torture_deferred_free,
.sync = srcu_torture_synchronize, .sync = srcu_torture_synchronize,
...@@ -787,6 +803,7 @@ static struct rcu_torture_ops trivial_ops = { ...@@ -787,6 +803,7 @@ static struct rcu_torture_ops trivial_ops = {
.readlock = rcu_torture_read_lock_trivial, .readlock = rcu_torture_read_lock_trivial,
.read_delay = rcu_read_delay, /* just reuse rcu's version. */ .read_delay = rcu_read_delay, /* just reuse rcu's version. */
.readunlock = rcu_torture_read_unlock_trivial, .readunlock = rcu_torture_read_unlock_trivial,
.readlock_held = torture_readlock_not_held,
.get_gp_seq = rcu_no_completed, .get_gp_seq = rcu_no_completed,
.sync = synchronize_rcu_trivial, .sync = synchronize_rcu_trivial,
.exp_sync = synchronize_rcu_trivial, .exp_sync = synchronize_rcu_trivial,
...@@ -850,6 +867,7 @@ static struct rcu_torture_ops tasks_tracing_ops = { ...@@ -850,6 +867,7 @@ static struct rcu_torture_ops tasks_tracing_ops = {
.readlock = tasks_tracing_torture_read_lock, .readlock = tasks_tracing_torture_read_lock,
.read_delay = srcu_read_delay, /* just reuse srcu's version. */ .read_delay = srcu_read_delay, /* just reuse srcu's version. */
.readunlock = tasks_tracing_torture_read_unlock, .readunlock = tasks_tracing_torture_read_unlock,
.readlock_held = rcu_read_lock_trace_held,
.get_gp_seq = rcu_no_completed, .get_gp_seq = rcu_no_completed,
.deferred_free = rcu_tasks_tracing_torture_deferred_free, .deferred_free = rcu_tasks_tracing_torture_deferred_free,
.sync = synchronize_rcu_tasks_trace, .sync = synchronize_rcu_tasks_trace,
...@@ -871,11 +889,6 @@ static unsigned long rcutorture_seq_diff(unsigned long new, unsigned long old) ...@@ -871,11 +889,6 @@ static unsigned long rcutorture_seq_diff(unsigned long new, unsigned long old)
return cur_ops->gp_diff(new, old); return cur_ops->gp_diff(new, old);
} }
static bool __maybe_unused torturing_tasks(void)
{
return cur_ops == &tasks_ops || cur_ops == &tasks_rude_ops;
}
/* /*
* RCU torture priority-boost testing. Runs one real-time thread per * RCU torture priority-boost testing. Runs one real-time thread per
* CPU for moderate bursts, repeatedly registering RCU callbacks and * CPU for moderate bursts, repeatedly registering RCU callbacks and
...@@ -1553,11 +1566,7 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) ...@@ -1553,11 +1566,7 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid)
started = cur_ops->get_gp_seq(); started = cur_ops->get_gp_seq();
ts = rcu_trace_clock_local(); ts = rcu_trace_clock_local();
p = rcu_dereference_check(rcu_torture_current, p = rcu_dereference_check(rcu_torture_current,
rcu_read_lock_bh_held() || !cur_ops->readlock_held || cur_ops->readlock_held());
rcu_read_lock_sched_held() ||
srcu_read_lock_held(srcu_ctlp) ||
rcu_read_lock_trace_held() ||
torturing_tasks());
if (p == NULL) { if (p == NULL) {
/* Wait for rcu_torture_writer to get underway */ /* Wait for rcu_torture_writer to get underway */
rcutorture_one_extend(&readstate, 0, trsp, rtrsp); rcutorture_one_extend(&readstate, 0, trsp, rtrsp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment