aboutsummaryrefslogtreecommitdiffstats
path: root/include/trace
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2012-04-30 17:16:19 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-05-09 17:26:56 -0400
commit21e52e15666323078b8517a4312712579176b56f (patch)
tree6e9e75c6e1400e0426a7c7985a3f986fea5a7782 /include/trace
parentf511fc624642f0bb8cf65aaa28979737514d4746 (diff)
rcu: Make RCU_FAST_NO_HZ handle timer migration
The current RCU_FAST_NO_HZ assumes that timers do not migrate unless a CPU goes offline, in which case it assumes that the CPU will have to come out of dyntick-idle mode (cancelling the timer) in order to go offline. This is important because when RCU_FAST_NO_HZ permits a CPU to enter dyntick-idle mode despite having RCU callbacks pending, it posts a timer on that CPU to force a wakeup on that CPU. This wakeup ensures that the CPU will eventually handle the end of the grace period, including invoking its RCU callbacks. However, Pascal Chapperon's test setup shows that the timer handler rcu_idle_gp_timer_func() really does get invoked in some cases. This is problematic because this can cause the CPU that entered dyntick-idle mode despite still having RCU callbacks pending to remain in dyntick-idle mode indefinitely, which means that its RCU callbacks might never be invoked. This situation can result in grace-period delays or even system hangs, which matches Pascal's observations of slow boot-up and shutdown (https://lkml.org/lkml/2012/4/5/142). See also the bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=806548 This commit therefore causes the "should never be invoked" timer handler rcu_idle_gp_timer_func() to use smp_call_function_single() to wake up the CPU for which the timer was intended, allowing that CPU to invoke its RCU callbacks in a timely manner. Reported-by: Pascal Chapperon <pascal.chapperon@wanadoo.fr> Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'include/trace')
-rw-r--r--include/trace/events/rcu.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index aaa55e1b8c48..1480900c511c 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -292,6 +292,7 @@ TRACE_EVENT(rcu_dyntick,
292 * "More callbacks": Still more callbacks, try again to clear them out. 292 * "More callbacks": Still more callbacks, try again to clear them out.
293 * "Callbacks drained": All callbacks processed, off to dyntick idle! 293 * "Callbacks drained": All callbacks processed, off to dyntick idle!
294 * "Timer": Timer fired to cause CPU to continue processing callbacks. 294 * "Timer": Timer fired to cause CPU to continue processing callbacks.
295 * "Demigrate": Timer fired on wrong CPU, woke up correct CPU.
295 * "Cleanup after idle": Idle exited, timer canceled. 296 * "Cleanup after idle": Idle exited, timer canceled.
296 */ 297 */
297TRACE_EVENT(rcu_prep_idle, 298TRACE_EVENT(rcu_prep_idle,