From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752760AbbKKMXV (ORCPT ); Wed, 11 Nov 2015 07:23:21 -0500 Received: from casper.infradead.org ([85.118.1.10]:43515 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751508AbbKKMXO (ORCPT ); Wed, 11 Nov 2015 07:23:14 -0500 Date: Wed, 11 Nov 2015 13:23:10 +0100 From: Peter Zijlstra To: Paul McKenney , Steven Rostedt Cc: Oleg Nesterov , Ingo Molnar , linux-kernel@vger.kernel.org Subject: [RFC][PATCH] rcu: Clean up TASKS_RCU() abuse Message-ID: <20151111122310.GO17308@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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) --- 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