rcutorture: Add torture tests for RCU Tasks Trace
authorPaul E. McKenney <paulmck@kernel.org>
Tue, 10 Mar 2020 17:32:30 +0000 (10:32 -0700)
committerPaul E. McKenney <paulmck@kernel.org>
Mon, 27 Apr 2020 18:03:51 +0000 (11:03 -0700)
This commit adds the definitions required to torture the tracing flavor
of RCU tasks.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
kernel/rcu/Kconfig.debug
kernel/rcu/rcu.h
kernel/rcu/rcutorture.c
tools/testing/selftests/rcutorture/configs/rcu/CFLIST
tools/testing/selftests/rcutorture/configs/rcu/TRACE01 [new file with mode: 0644]
tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot [new file with mode: 0644]

index b5f3545..452feae 100644 (file)
@@ -30,6 +30,7 @@ config RCU_PERF_TEST
        select SRCU
        select TASKS_RCU
        select TASKS_RUDE_RCU
+       select TASKS_TRACE_RCU
        default n
        help
          This option provides a kernel module that runs performance
@@ -48,6 +49,7 @@ config RCU_TORTURE_TEST
        select SRCU
        select TASKS_RCU
        select TASKS_RUDE_RCU
+       select TASKS_TRACE_RCU
        default n
        help
          This option provides a kernel module that runs torture tests
index c574620..7290386 100644 (file)
@@ -442,6 +442,7 @@ enum rcutorture_type {
        RCU_FLAVOR,
        RCU_TASKS_FLAVOR,
        RCU_TASKS_RUDE_FLAVOR,
+       RCU_TASKS_TRACING_FLAVOR,
        RCU_TRIVIAL_FLAVOR,
        SRCU_FLAVOR,
        INVALID_RCU_FLAVOR
index 6b06638..0bec925 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/sched/sysctl.h>
 #include <linux/oom.h>
 #include <linux/tick.h>
+#include <linux/rcupdate_trace.h>
 
 #include "rcu.h"
 
@@ -757,6 +758,45 @@ static struct rcu_torture_ops tasks_rude_ops = {
        .name           = "tasks-rude"
 };
 
+/*
+ * Definitions for tracing RCU-tasks torture testing.
+ */
+
+static int tasks_tracing_torture_read_lock(void)
+{
+       rcu_read_lock_trace();
+       return 0;
+}
+
+static void tasks_tracing_torture_read_unlock(int idx)
+{
+       rcu_read_unlock_trace();
+}
+
+static void rcu_tasks_tracing_torture_deferred_free(struct rcu_torture *p)
+{
+       call_rcu_tasks_trace(&p->rtort_rcu, rcu_torture_cb);
+}
+
+static struct rcu_torture_ops tasks_tracing_ops = {
+       .ttype          = RCU_TASKS_TRACING_FLAVOR,
+       .init           = rcu_sync_torture_init,
+       .readlock       = tasks_tracing_torture_read_lock,
+       .read_delay     = srcu_read_delay,  /* just reuse srcu's version. */
+       .readunlock     = tasks_tracing_torture_read_unlock,
+       .get_gp_seq     = rcu_no_completed,
+       .deferred_free  = rcu_tasks_tracing_torture_deferred_free,
+       .sync           = synchronize_rcu_tasks_trace,
+       .exp_sync       = synchronize_rcu_tasks_trace,
+       .call           = call_rcu_tasks_trace,
+       .cb_barrier     = rcu_barrier_tasks_trace,
+       .fqs            = NULL,
+       .stats          = NULL,
+       .irq_capable    = 1,
+       .slow_gps       = 1,
+       .name           = "tasks-tracing"
+};
+
 static unsigned long rcutorture_seq_diff(unsigned long new, unsigned long old)
 {
        if (!cur_ops->gp_diff)
@@ -1323,6 +1363,7 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp)
                                  rcu_read_lock_bh_held() ||
                                  rcu_read_lock_sched_held() ||
                                  srcu_read_lock_held(srcu_ctlp) ||
+                                 rcu_read_lock_trace_held() ||
                                  torturing_tasks());
        if (p == NULL) {
                /* Wait for rcu_torture_writer to get underway */
@@ -2440,7 +2481,8 @@ rcu_torture_init(void)
        int firsterr = 0;
        static struct rcu_torture_ops *torture_ops[] = {
                &rcu_ops, &rcu_busted_ops, &srcu_ops, &srcud_ops,
-               &busted_srcud_ops, &tasks_ops, &tasks_rude_ops, &trivial_ops,
+               &busted_srcud_ops, &tasks_ops, &tasks_rude_ops,
+               &tasks_tracing_ops, &trivial_ops,
        };
 
        if (!torture_init_begin(torture_type, verbose))
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01
new file mode 100644 (file)
index 0000000..078e2c1
--- /dev/null
@@ -0,0 +1,10 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=y
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=n
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+#CHECK#CONFIG_PROVE_RCU=y
+CONFIG_RCU_EXPERT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot
new file mode 100644 (file)
index 0000000..9675ad6
--- /dev/null
@@ -0,0 +1 @@
+rcutorture.torture_type=tasks-tracing