aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sched.h4
-rw-r--r--kernel/sched/core.c20
-rw-r--r--kernel/timer.c12
3 files changed, 27 insertions, 9 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9004f6e19eac..10626e2ee688 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1851,9 +1851,9 @@ static inline void idle_task_exit(void) {}
1851#endif 1851#endif
1852 1852
1853#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) 1853#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
1854extern void wake_up_idle_cpu(int cpu); 1854extern void wake_up_nohz_cpu(int cpu);
1855#else 1855#else
1856static inline void wake_up_idle_cpu(int cpu) { } 1856static inline void wake_up_nohz_cpu(int cpu) { }
1857#endif 1857#endif
1858 1858
1859#ifdef CONFIG_SCHED_AUTOGROUP 1859#ifdef CONFIG_SCHED_AUTOGROUP
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 849deb96e61e..e91ee589f793 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -587,7 +587,7 @@ unlock:
587 * account when the CPU goes back to idle and evaluates the timer 587 * account when the CPU goes back to idle and evaluates the timer
588 * wheel for the next timer event. 588 * wheel for the next timer event.
589 */ 589 */
590void wake_up_idle_cpu(int cpu) 590static void wake_up_idle_cpu(int cpu)
591{ 591{
592 struct rq *rq = cpu_rq(cpu); 592 struct rq *rq = cpu_rq(cpu);
593 593
@@ -617,6 +617,24 @@ void wake_up_idle_cpu(int cpu)
617 smp_send_reschedule(cpu); 617 smp_send_reschedule(cpu);
618} 618}
619 619
620static bool wake_up_extended_nohz_cpu(int cpu)
621{
622 if (tick_nohz_extended_cpu(cpu)) {
623 if (cpu != smp_processor_id() ||
624 tick_nohz_tick_stopped())
625 smp_send_reschedule(cpu);
626 return true;
627 }
628
629 return false;
630}
631
632void wake_up_nohz_cpu(int cpu)
633{
634 if (!wake_up_extended_nohz_cpu(cpu))
635 wake_up_idle_cpu(cpu);
636}
637
620static inline bool got_nohz_idle_kick(void) 638static inline bool got_nohz_idle_kick(void)
621{ 639{
622 int cpu = smp_processor_id(); 640 int cpu = smp_processor_id();
diff --git a/kernel/timer.c b/kernel/timer.c
index dbf7a78a1ef1..4e3040b40d16 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -930,14 +930,14 @@ void add_timer_on(struct timer_list *timer, int cpu)
930 debug_activate(timer, timer->expires); 930 debug_activate(timer, timer->expires);
931 internal_add_timer(base, timer); 931 internal_add_timer(base, timer);
932 /* 932 /*
933 * Check whether the other CPU is idle and needs to be 933 * Check whether the other CPU is in dynticks mode and needs
934 * triggered to reevaluate the timer wheel when nohz is 934 * to be triggered to reevaluate the timer wheel.
935 * active. We are protected against the other CPU fiddling 935 * We are protected against the other CPU fiddling
936 * with the timer by holding the timer base lock. This also 936 * with the timer by holding the timer base lock. This also
937 * makes sure that a CPU on the way to idle can not evaluate 937 * makes sure that a CPU on the way to stop its tick can not
938 * the timer wheel. 938 * evaluate the timer wheel.
939 */ 939 */
940 wake_up_idle_cpu(cpu); 940 wake_up_nohz_cpu(cpu);
941 spin_unlock_irqrestore(&base->lock, flags); 941 spin_unlock_irqrestore(&base->lock, flags);
942} 942}
943EXPORT_SYMBOL_GPL(add_timer_on); 943EXPORT_SYMBOL_GPL(add_timer_on);