aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2012-07-11 14:26:30 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2012-09-26 09:44:04 -0400
commit2b1d5024e17be459aa6385763ca3faa8f01c52d9 (patch)
tree45d1ea5872eea69b7f0443086d98ddbcbc221b94
parent9a0c6fef423528ba5b62aa31b29aabf689eb8f70 (diff)
rcu: Settle config for userspace extended quiescent state
Create a new config option under the RCU menu that put CPUs under RCU extended quiescent state (as in dynticks idle mode) when they run in userspace. This require some contribution from architectures to hook into kernel and userspace boundaries. 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>
-rw-r--r--arch/Kconfig10
-rw-r--r--include/linux/rcupdate.h9
-rw-r--r--init/Kconfig10
-rw-r--r--kernel/rcutree.c5
4 files changed, 33 insertions, 1 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 72f2fa189cc5..1401a7587973 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -281,4 +281,14 @@ config SECCOMP_FILTER
281 281
282 See Documentation/prctl/seccomp_filter.txt for details. 282 See Documentation/prctl/seccomp_filter.txt for details.
283 283
284config HAVE_RCU_USER_QS
285 bool
286 help
287 Provide kernel entry/exit hooks necessary for userspace
288 RCU extended quiescent state. Syscalls need to be wrapped inside
289 rcu_user_exit()-rcu_user_enter() through the slow path using
290 TIF_NOHZ flag. Exceptions handlers must be wrapped as well. Irqs
291 are already protected inside rcu_irq_enter/rcu_irq_exit() but
292 preemption or signal handling on irq exit still need to be protected.
293
284source "kernel/gcov/Kconfig" 294source "kernel/gcov/Kconfig"
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index f818dd165b44..f5034f22e94b 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -191,10 +191,19 @@ extern void rcu_idle_enter(void);
191extern void rcu_idle_exit(void); 191extern void rcu_idle_exit(void);
192extern void rcu_irq_enter(void); 192extern void rcu_irq_enter(void);
193extern void rcu_irq_exit(void); 193extern void rcu_irq_exit(void);
194
195#ifdef CONFIG_RCU_USER_QS
194extern void rcu_user_enter(void); 196extern void rcu_user_enter(void);
195extern void rcu_user_exit(void); 197extern void rcu_user_exit(void);
196extern void rcu_user_enter_after_irq(void); 198extern void rcu_user_enter_after_irq(void);
197extern void rcu_user_exit_after_irq(void); 199extern void rcu_user_exit_after_irq(void);
200#else
201static inline void rcu_user_enter(void) { }
202static inline void rcu_user_exit(void) { }
203static inline void rcu_user_enter_after_irq(void) { }
204static inline void rcu_user_exit_after_irq(void) { }
205#endif /* CONFIG_RCU_USER_QS */
206
198extern void exit_rcu(void); 207extern void exit_rcu(void);
199 208
200/** 209/**
diff --git a/init/Kconfig b/init/Kconfig
index af6c7f8ba019..f6a1830165ce 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -441,6 +441,16 @@ config PREEMPT_RCU
441 This option enables preemptible-RCU code that is common between 441 This option enables preemptible-RCU code that is common between
442 the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations. 442 the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations.
443 443
444config RCU_USER_QS
445 bool "Consider userspace as in RCU extended quiescent state"
446 depends on HAVE_RCU_USER_QS && SMP
447 help
448 This option sets hooks on kernel / userspace boundaries and
449 puts RCU in extended quiescent state when the CPU runs in
450 userspace. It means that when a CPU runs in userspace, it is
451 excluded from the global RCU state machine and thus doesn't
452 to keep the timer tick on for RCU.
453
444config RCU_FANOUT 454config RCU_FANOUT
445 int "Tree-based hierarchical RCU fanout value" 455 int "Tree-based hierarchical RCU fanout value"
446 range 2 64 if 64BIT 456 range 2 64 if 64BIT
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 4138f59fa2f4..79fa2db1595b 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -400,6 +400,7 @@ void rcu_idle_enter(void)
400} 400}
401EXPORT_SYMBOL_GPL(rcu_idle_enter); 401EXPORT_SYMBOL_GPL(rcu_idle_enter);
402 402
403#ifdef CONFIG_RCU_USER_QS
403/** 404/**
404 * rcu_user_enter - inform RCU that we are resuming userspace. 405 * rcu_user_enter - inform RCU that we are resuming userspace.
405 * 406 *
@@ -424,7 +425,6 @@ void rcu_user_enter(void)
424 rcu_eqs_enter(1); 425 rcu_eqs_enter(1);
425} 426}
426 427
427
428/** 428/**
429 * rcu_user_enter_after_irq - inform RCU that we are going to resume userspace 429 * rcu_user_enter_after_irq - inform RCU that we are going to resume userspace
430 * after the current irq returns. 430 * after the current irq returns.
@@ -445,6 +445,7 @@ void rcu_user_enter_after_irq(void)
445 rdtp->dynticks_nesting = 1; 445 rdtp->dynticks_nesting = 1;
446 local_irq_restore(flags); 446 local_irq_restore(flags);
447} 447}
448#endif /* CONFIG_RCU_USER_QS */
448 449
449/** 450/**
450 * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle 451 * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
@@ -548,6 +549,7 @@ void rcu_idle_exit(void)
548} 549}
549EXPORT_SYMBOL_GPL(rcu_idle_exit); 550EXPORT_SYMBOL_GPL(rcu_idle_exit);
550 551
552#ifdef CONFIG_RCU_USER_QS
551/** 553/**
552 * rcu_user_exit - inform RCU that we are exiting userspace. 554 * rcu_user_exit - inform RCU that we are exiting userspace.
553 * 555 *
@@ -591,6 +593,7 @@ void rcu_user_exit_after_irq(void)
591 rdtp->dynticks_nesting += DYNTICK_TASK_EXIT_IDLE; 593 rdtp->dynticks_nesting += DYNTICK_TASK_EXIT_IDLE;
592 local_irq_restore(flags); 594 local_irq_restore(flags);
593} 595}
596#endif /* CONFIG_RCU_USER_QS */
594 597
595/** 598/**
596 * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle 599 * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle