smp_send_reschedule(cpu);
}
-static bool wake_up_extended_nohz_cpu(int cpu)
+static bool wake_up_full_nohz_cpu(int cpu)
{
- if (tick_nohz_extended_cpu(cpu)) {
+ if (tick_nohz_full_cpu(cpu)) {
if (cpu != smp_processor_id() ||
tick_nohz_tick_stopped())
smp_send_reschedule(cpu);
void wake_up_nohz_cpu(int cpu)
{
- if (!wake_up_extended_nohz_cpu(cpu))
+ if (!wake_up_full_nohz_cpu(cpu))
wake_up_idle_cpu(cpu);
}
#endif /* CONFIG_NO_HZ_COMMON */
+#ifdef CONFIG_NO_HZ_FULL
+bool sched_can_stop_tick(void)
+{
+ struct rq *rq;
+
+ rq = this_rq();
+
+ /* Make sure rq->nr_running update is visible after the IPI */
+ smp_rmb();
+
+ /* More than one running task need preemption */
+ if (rq->nr_running > 1)
+ return false;
+
+ return true;
+}
+#endif /* CONFIG_NO_HZ_FULL */
+
void sched_avg_update(struct rq *rq)
{
s64 period = sched_avg_period();
void scheduler_ipi(void)
{
- if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick())
+ if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()
+ && !tick_nohz_full_cpu(smp_processor_id()))
return;
/*
* somewhat pessimize the simple resched case.
*/
irq_enter();
+ tick_nohz_full_check();
sched_ttwu_pending();
/*
kprobe_flush_task(prev);
put_task_struct(prev);
}
+
+ tick_nohz_task_switch(current);
}
#ifdef CONFIG_SMP