rcu: Drive TASKS_RCU directly off of PREEMPT
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 25 May 2017 15:05:00 +0000 (08:05 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 17 Aug 2017 14:26:04 +0000 (07:26 -0700)
The actual use of TASKS_RCU is only when PREEMPT, otherwise RCU-sched
is used instead.  This commit therefore makes synchronize_rcu_tasks()
and call_rcu_tasks() available always, but mapped to synchronize_sched()
and call_rcu_sched(), respectively, when !PREEMPT.  This approach also
allows some #ifdefs to be removed from rcutorture.

Reported-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Ingo Molnar <mingo@kernel.org>
include/linux/rcupdate.h
kernel/rcu/Kconfig
kernel/rcu/rcutorture.c
tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt

index f816fc72b51eeda73bf55f7d7176b25cdb27f110..c3f380befdd7c190da84b977b9832201745b8fb3 100644 (file)
@@ -58,8 +58,6 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func);
 void call_rcu_bh(struct rcu_head *head, rcu_callback_t func);
 void call_rcu_sched(struct rcu_head *head, rcu_callback_t func);
 void synchronize_sched(void);
-void call_rcu_tasks(struct rcu_head *head, rcu_callback_t func);
-void synchronize_rcu_tasks(void);
 void rcu_barrier_tasks(void);
 
 #ifdef CONFIG_PREEMPT_RCU
@@ -176,10 +174,14 @@ extern struct srcu_struct tasks_rcu_exit_srcu;
                rcu_all_qs(); \
                rcu_note_voluntary_context_switch_lite(t); \
        } while (0)
+void call_rcu_tasks(struct rcu_head *head, rcu_callback_t func);
+void synchronize_rcu_tasks(void);
 #else /* #ifdef CONFIG_TASKS_RCU */
 #define TASKS_RCU(x) do { } while (0)
 #define rcu_note_voluntary_context_switch_lite(t)      do { } while (0)
 #define rcu_note_voluntary_context_switch(t)           rcu_all_qs()
+#define call_rcu_tasks call_rcu_sched
+#define synchronize_rcu_tasks synchronize_sched
 #endif /* #else #ifdef CONFIG_TASKS_RCU */
 
 /**
index be90c945063f46b7ba1368aed5c6fc970e9b6e98..9210379c0353676b79bc92e0c872fb41f1ba5693 100644 (file)
@@ -69,8 +69,7 @@ config TREE_SRCU
          This option selects the full-fledged version of SRCU.
 
 config TASKS_RCU
-       bool
-       default n
+       def_bool PREEMPT
        select SRCU
        help
          This option enables a task-based RCU implementation that uses
index b8f7f8ce8575dda9092cbaa18f1134b0cf1a06c5..b284c861a5112a8cc6a292f206e369cc3fffff03 100644 (file)
@@ -696,8 +696,6 @@ static struct rcu_torture_ops sched_ops = {
        .name           = "sched"
 };
 
-#ifdef CONFIG_TASKS_RCU
-
 /*
  * Definitions for RCU-tasks torture testing.
  */
@@ -735,24 +733,11 @@ static struct rcu_torture_ops tasks_ops = {
        .name           = "tasks"
 };
 
-#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 __maybe_unused torturing_tasks(void)
-{
-       return false;
-}
-
-#endif /* #else #ifdef CONFIG_TASKS_RCU */
-
 /*
  * RCU torture priority-boost testing.  Runs one real-time thread per
  * CPU for moderate bursts, repeatedly registering RCU callbacks and
@@ -1749,7 +1734,7 @@ rcu_torture_init(void)
        int firsterr = 0;
        static struct rcu_torture_ops *torture_ops[] = {
                &rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &srcud_ops,
-               &sched_ops, RCUTORTURE_TASKS_OPS
+               &sched_ops, &tasks_ops,
        };
 
        if (!torture_init_begin(torture_type, verbose, &torture_runnable))
index 9ad3f89c8dc7499c5a4cd804d9d34c6dbcff9603..af6fca03602fbec9b7acbf7295e68d27f7215d3f 100644 (file)
@@ -69,11 +69,11 @@ CONFIG_RCU_TORTURE_TEST_RUNNABLE
 CONFIG_PREEMPT_RCU
 CONFIG_TREE_RCU
 CONFIG_TINY_RCU
+CONFIG_TASKS_RCU
 
        These are controlled by CONFIG_PREEMPT and/or CONFIG_SMP.
 
 CONFIG_SRCU
-CONFIG_TASKS_RCU
 
        Selected by CONFIG_RCU_TORTURE_TEST, so cannot disable.