rcu: Clean up TASKS_RCU() abuse
RFC PATCH 1/1 rcu: Clean up TASKS_RCU() abuse
Hi
I recently ran into TASKS_RCU() and wondered why we can't use normal coding patterns to do the same.
--- include/linux/rcupdate.h | 33 +++++++++++++++++++++++++++++++-- kernel/exit.c | 9 +++------ 2 files changed, 34 insertions(+), 8 deletions(-)
include/linux/rcupdate.h +31 -2
@@ -389,7 +389,7 @@ static inline void rcu_init_nohz(void)* macro rather than an inline function to avoid #include hell. */ #ifdef CONFIG_TASKS_RCU -#define TASKS_RCU (x) x +extern struct srcu_struct tasks_rcu_exit_srcu;#define rcu_note_voluntary_context_switch (t) \ do { \
@@ -397,9 +397,38 @@ extern struct srcu_struct tasks_rcu_exit_srcu;if (READ_ONCE ((t)->rcu_tasks_holdout)) \WRITE_ONCE ((t)->rcu_tasks_holdout, false); \ } while (0) + +static inline int tasks_rcu_read_lock(void) +{ +int idx; + +preempt_disable (); + idx =__srcu_read_lock (&tasks_rcu_exit_srcu); +preempt_enable (); + +return idx; +} + +static inline void tasks_rcu_read_unlock (int idx) +{ +preempt_disable (); +__srcu_read_unlock (&tasks_rcu_exit_srcu, idx); +preempt_enable (); +} +#else /* #ifdef CONFIG_TASKS_RCU */ -#define TASKS_RCU (x) do { } while (0) +#define rcu_note_voluntary_context_switch (t) rcu_all_qs() + +static inline int tasks_rcu_read_lock (void ) +{ +return 0 ; +} + +static inline void tasks_rcu_read_unlock (int idx) +{ +} +#endif /* #else #ifdef CONFIG_TASKS_RCU */ /**
kernel/exit.c +3 -6
@@ -653,8 +653,7 @@ static inline void check_stack_usage(void) {}void do_exit (long code) {struct task_struct *tsk = current; -int group_dead; - TASKS_RCU(int tasks_rcu_i); +int group_dead, tasks_rcu_i;profile_task_exit (tsk);
@@ -763,9 +762,7 @@ void do_exit(long code)*/ flush_ptrace_hw_breakpoint (tsk); -TASKS_RCU (preempt_disable ()); -TASKS_RCU (tasks_rcu_i =__srcu_read_lock (&tasks_rcu_exit_srcu)); -TASKS_RCU (preempt_enable ()); + tasks_rcu_i =tasks_rcu_read_lock ();exit_notify (tsk, group_dead);proc_exit_connector (tsk);#ifdef CONFIG_NUMA
@@ -805,7 +802,7 @@ void do_exit(long code)if (tsk->nr_dirtied)__this_cpu_add (dirty_throttle_leaks, tsk->nr_dirtied);exit_rcu (); -TASKS_RCU (__srcu_read_unlock (&tasks_rcu_exit_srcu, tasks_rcu_i)); +tasks_rcu_read_unlock (tasks_rcu_i);/* * The setting of TASK_RUNNING by try_to_wake_up() may be delayed
Quoted 6 lines · Peter Zijlstra
Hi
I recently ran into
TASKS_RCU()and wondered why we can't use normal coding patterns to do the same.Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Well, I cannot get too excited either way, but the diffstat for this change is not particularly favorable.
Thanx, Paul
Quoted 93 lines
--- include/linux/rcupdate.h | 33 +++++++++++++++++++++++++++++++-- kernel/exit.c | 9 +++------ 2 files changed, 34 insertions(+), 8 deletions(-)include/linux/rcupdate.h +31
-2@@ -389,7 +389,7 @@ static inline void rcu_init_nohz(void)* macro rather than an inline function to avoid #include hell. */ #ifdef CONFIG_TASKS_RCU -#define TASKS_RCU (x) x +extern struct srcu_struct tasks_rcu_exit_srcu;#define rcu_note_voluntary_context_switch (t) \ do { \@@ -397,9 +397,38 @@ extern struct srcu_struct tasks_rcu_exit_srcu;if (READ_ONCE ((t)->rcu_tasks_holdout)) \WRITE_ONCE ((t)->rcu_tasks_holdout, false); \ } while (0) + +static inline int tasks_rcu_read_lock(void) +{ +int idx; + +preempt_disable (); + idx =__srcu_read_lock (&tasks_rcu_exit_srcu); +preempt_enable (); + +return idx; +} + +static inline void tasks_rcu_read_unlock (int idx) +{ +preempt_disable (); +__srcu_read_unlock (&tasks_rcu_exit_srcu, idx); +preempt_enable (); +} +#else /* #ifdef CONFIG_TASKS_RCU */ -#define TASKS_RCU (x) do { } while (0) +#define rcu_note_voluntary_context_switch (t) rcu_all_qs() + +static inline int tasks_rcu_read_lock (void ) +{ +return 0 ; +} + +static inline void tasks_rcu_read_unlock (int idx) +{ +} +#endif /* #else #ifdef CONFIG_TASKS_RCU */ /** kernel/exit.c +3
-6@@ -653,8 +653,7 @@ static inline void check_stack_usage(void) {}void do_exit (long code) {struct task_struct *tsk = current; -int group_dead; - TASKS_RCU(int tasks_rcu_i); +int group_dead, tasks_rcu_i;profile_task_exit (tsk);@@ -763,9 +762,7 @@ void do_exit(long code)*/ flush_ptrace_hw_breakpoint (tsk); -TASKS_RCU (preempt_disable ()); -TASKS_RCU (tasks_rcu_i =__srcu_read_lock (&tasks_rcu_exit_srcu)); -TASKS_RCU (preempt_enable ()); + tasks_rcu_i =tasks_rcu_read_lock ();exit_notify (tsk, group_dead);proc_exit_connector (tsk);#ifdef CONFIG_NUMA @@ -805,7 +802,7 @@ void do_exit(long code)if (tsk->nr_dirtied)__this_cpu_add (dirty_throttle_leaks, tsk->nr_dirtied);exit_rcu (); -TASKS_RCU (__srcu_read_unlock (&tasks_rcu_exit_srcu, tasks_rcu_i)); +tasks_rcu_read_unlock (tasks_rcu_i);/* * The setting of TASK_RUNNING by try_to_wake_up() may be delayed
Quoted 10 lines · Paul E. McKenney
Quoted 6 lines · Peter Zijlstra
Hi
I recently ran into
TASKS_RCU()and wondered why we can't use normal coding patterns to do the same.Signed-off-by Peter Zijlstra (Intel) <[email protected]>Well, I cannot get too excited either way, but the diffstat for this change is not particularly favorable.
It also doesn't build with TASKS_RCU enabled it turns out. But the point is, nowhere else do we use this pattern. We always provide functions.
Quoted 7 lines · Peter Zijlstra
Quoted 6 lines · Paul E. McKenney
Quoted 5 lines · Peter Zijlstra
Hi
I recently ran into
TASKS_RCU()and wondered why we can't use normal coding patterns to do the same.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Signed-off-by Peter Zijlstra (Intel) <[email protected]>Well, I cannot get too excited either way, but the diffstat for this change is not particularly favorable.
It also doesn't build with
TASKS_RCUenabled it turns out. But the point is, nowhere else do we use this pattern. We always provide functions.
RCU_TRACE() another very similar macro, and has been in place for quite some time. Still within RCU, admittedly, but it does exist.
Thanx, Paul