]> git.karo-electronics.de Git - linux-beck.git/commitdiff
rcutorture: Add RCU-tasks qualifier to dereference
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 30 Jun 2015 15:57:57 +0000 (08:57 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Wed, 15 Jul 2015 21:47:19 +0000 (14:47 -0700)
Although RCU-tasks isn't really designed to support rcu_dereference()
and list manipulation, that is how rcutorture tests it.  Which means
that lockdep-RCU complains about the rcu_dereference_check() invocations
because RCU-tasks doesn't have read-side markers.  This commit therefore
creates a torturing_tasks() to silence the lockdep-RCU complaints from
rcu_dereference_check() when RCU-tasks is being tortured.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
kernel/rcu/rcutorture.c

index e0eda3c1b621acf28c8e96aee4a79fd438f2b2e8..67b3f260720eb4ba24e1c83c3fa41093c30e11da 100644 (file)
@@ -684,10 +684,20 @@ static struct rcu_torture_ops tasks_ops = {
 
 #define RCUTORTURE_TASKS_OPS &tasks_ops,
 
+static bool __maybe_unused torturing_tasks(void)
+{
+       return cur_ops == &tasks_ops;
+}
+
 #else /* #ifdef CONFIG_TASKS_RCU */
 
 #define RCUTORTURE_TASKS_OPS
 
+static bool torturing_tasks(void)
+{
+       return false;
+}
+
 #endif /* #else #ifdef CONFIG_TASKS_RCU */
 
 /*
@@ -1087,7 +1097,8 @@ static void rcu_torture_timer(unsigned long unused)
        p = rcu_dereference_check(rcu_torture_current,
                                  rcu_read_lock_bh_held() ||
                                  rcu_read_lock_sched_held() ||
-                                 srcu_read_lock_held(srcu_ctlp));
+                                 srcu_read_lock_held(srcu_ctlp) ||
+                                 torturing_tasks());
        if (p == NULL) {
                /* Leave because rcu_torture_writer is not yet underway */
                cur_ops->readunlock(idx);
@@ -1161,7 +1172,8 @@ rcu_torture_reader(void *arg)
                p = rcu_dereference_check(rcu_torture_current,
                                          rcu_read_lock_bh_held() ||
                                          rcu_read_lock_sched_held() ||
-                                         srcu_read_lock_held(srcu_ctlp));
+                                         srcu_read_lock_held(srcu_ctlp) ||
+                                         torturing_tasks());
                if (p == NULL) {
                        /* Wait for rcu_torture_writer to get underway */
                        cur_ops->readunlock(idx);