diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 63b182e72b67..6c6384153c55 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -671,7 +671,7 @@ int get_nohz_timer_target(void) int i, cpu = smp_processor_id(), default_cpu = -1; struct sched_domain *sd; - if (housekeeping_cpu(cpu, HK_FLAG_TIMER)) { + if (housekeeping_cpu(cpu, HK_FLAG_TIMER) && cpu_active(cpu)) { if (!idle_cpu(cpu)) return cpu; default_cpu = cpu; @@ -691,8 +691,25 @@ int get_nohz_timer_target(void) } } - if (default_cpu == -1) - default_cpu = housekeeping_any_cpu(HK_FLAG_TIMER); + if (default_cpu == -1) { + for_each_cpu_and(i, cpu_active_mask, + housekeeping_cpumask(HK_FLAG_TIMER)) { + if (cpu == i) + continue; + + if (!idle_cpu(i)) { + cpu = i; + goto unlock; + } + } + + /* no active, not-idle, housekpeeing CPU found. */ + default_cpu = cpumask_any(cpu_active_mask); + + if (unlikely(default_cpu >= nr_cpu_ids)) + goto unlock; + } + cpu = default_cpu; unlock: rcu_read_unlock();