Messages in this thread Patch in this message | | | Date | Wed, 11 Nov 2015 13:23:10 +0100 | From | Peter Zijlstra <> | Subject | [RFC][PATCH] 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.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- include/linux/rcupdate.h | 33 +++++++++++++++++++++++++++++++-- kernel/exit.c | 9 +++------ 2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index a0189ba67fde..15a82372b372 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -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 */ /** diff --git a/kernel/exit.c b/kernel/exit.c index 07110c6020a0..cd5644baeb22 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -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
| |