sched: fix nohz load balancer on cpu offline
Christian Borntraeger reports: > After a logical cpu offline, even on a complete idle system, there > is one cpu with full ticks. It turns out that nohz.cpu_mask has the > the offlined cpu still set. > > In select_nohz_load_balancer() we check if the system is completely > idle to turn of load balancing. We compare cpu_online_map with > nohz.cpu_mask. Since cpu_online_map is updated on cpu unplug, > but nohz.cpu_mask is not, the check fails and the scheduler believes > that we need an "idle load balancer" even on a fully idle system. > Since the ilb cpu does not deactivate the timer tick this breaks NOHZ. Fix the select_nohz_load_balancer() to not set the nohz.cpu_mask while a cpu is going offline. Reported-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Tested-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
35626129ab
commit
483b4ee60e
@@ -3890,19 +3890,24 @@ int select_nohz_load_balancer(int stop_tick)
|
|||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
if (stop_tick) {
|
if (stop_tick) {
|
||||||
cpumask_set_cpu(cpu, nohz.cpu_mask);
|
|
||||||
cpu_rq(cpu)->in_nohz_recently = 1;
|
cpu_rq(cpu)->in_nohz_recently = 1;
|
||||||
|
|
||||||
/*
|
if (!cpu_active(cpu)) {
|
||||||
* If we are going offline and still the leader, give up!
|
if (atomic_read(&nohz.load_balancer) != cpu)
|
||||||
*/
|
return 0;
|
||||||
if (!cpu_active(cpu) &&
|
|
||||||
atomic_read(&nohz.load_balancer) == cpu) {
|
/*
|
||||||
|
* If we are going offline and still the leader,
|
||||||
|
* give up!
|
||||||
|
*/
|
||||||
if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
|
if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpumask_set_cpu(cpu, nohz.cpu_mask);
|
||||||
|
|
||||||
/* time for ilb owner also to sleep */
|
/* time for ilb owner also to sleep */
|
||||||
if (cpumask_weight(nohz.cpu_mask) == num_online_cpus()) {
|
if (cpumask_weight(nohz.cpu_mask) == num_online_cpus()) {
|
||||||
if (atomic_read(&nohz.load_balancer) == cpu)
|
if (atomic_read(&nohz.load_balancer) == cpu)
|
||||||
|
|||||||
Reference in New Issue
Block a user