diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2012-07-11 14:26:39 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2012-09-26 09:47:14 -0400 |
commit | edf55fda35c7dc7f2d9241c3abaddaf759b457c6 (patch) | |
tree | 5350fcb03d0a6db3a212e11787c598d1df184df0 /arch/x86/kernel/signal.c | |
parent | 0430499ce9d78691f3985962021b16bf8f8a8048 (diff) |
x86: Exit RCU extended QS on notify resume
do_notify_resume() may be called on irq or exception
exit. But at that time the exception has already called
rcu_user_enter() and the irq has already called rcu_irq_exit().
Since it can use RCU read side critical section, we must call
rcu_user_exit() before doing anything there. Then we must call
back rcu_user_enter() after this function because we know we are
going to userspace from there.
This complete support for userspace RCU extended quiescent state
in x86-64.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Alessio Igor Bogani <abogani@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Avi Kivity <avi@redhat.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Geoff Levand <geoff@infradead.org>
Cc: Gilad Ben Yossef <gilad@benyossef.com>
Cc: Hakan Akkan <hakanakkan@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Max Krasnyansky <maxk@qualcomm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Sven-Thorsten Dietrich <thebigcorporation@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'arch/x86/kernel/signal.c')
-rw-r--r-- | arch/x86/kernel/signal.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index b280908a376e..bca0ab903e57 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -779,6 +779,8 @@ static void do_signal(struct pt_regs *regs) | |||
779 | void | 779 | void |
780 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | 780 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) |
781 | { | 781 | { |
782 | rcu_user_exit(); | ||
783 | |||
782 | #ifdef CONFIG_X86_MCE | 784 | #ifdef CONFIG_X86_MCE |
783 | /* notify userspace of pending MCEs */ | 785 | /* notify userspace of pending MCEs */ |
784 | if (thread_info_flags & _TIF_MCE_NOTIFY) | 786 | if (thread_info_flags & _TIF_MCE_NOTIFY) |
@@ -804,6 +806,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
804 | #ifdef CONFIG_X86_32 | 806 | #ifdef CONFIG_X86_32 |
805 | clear_thread_flag(TIF_IRET); | 807 | clear_thread_flag(TIF_IRET); |
806 | #endif /* CONFIG_X86_32 */ | 808 | #endif /* CONFIG_X86_32 */ |
809 | |||
810 | rcu_user_enter(); | ||
807 | } | 811 | } |
808 | 812 | ||
809 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) | 813 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) |