[PATCH 05/13] rcu: Fix unraised IPI to timekeeping CPU

From: Frederic Weisbecker
Date: Tue Dec 17 2013 - 17:54:48 EST


The plan with full system idle detection is to allow the timekeeper
to sleep when all full dynticks CPUs are sleeping.

Then when a full dynticks CPU wakes up while the whole system is idle,
it sends an IPI to the timekeeping CPU which then restarts its tick
and polls on its timekeeping duty on behalf of all other CPUs in the
system.

But we are using rcu_kick_nohz_cpu() to raise this IPI, which is wrong
because this function is used to kick full dynticks CPUs when they run
in the kernel for too long without reporting a quiescent state. And
this function ignores targets that are not full dynticks, like our
timekeeper.

To fix this, use the smp_send_reschedule() function directly.

Signed-off-by: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx>
Cc: John Stultz <john.stultz@xxxxxxxxxx>
Cc: Alex Shi <alex.shi@xxxxxxxxxx>
Cc: Kevin Hilman <khilman@xxxxxxxxxx>
---
kernel/rcu/tree_plugin.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 08004da..84d90c8 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -2488,7 +2488,7 @@ void rcu_sysidle_force_exit(void)
oldstate, RCU_SYSIDLE_NOT);
if (oldstate == newoldstate &&
oldstate == RCU_SYSIDLE_FULL_NOTED) {
- rcu_kick_nohz_cpu(tick_do_timer_cpu);
+ smp_send_reschedule(tick_do_timer_cpu);
return; /* We cleared it, done! */
}
oldstate = newoldstate;
--
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/