diff options
author | Juri Lelli <juri.lelli@arm.com> | 2015-11-09 15:03:50 +0000 |
---|---|---|
committer | Todd Kjos <tkjos@google.com> | 2015-11-09 16:34:06 -0800 |
commit | 315852146bd8f190e82f472ec56f5ef411d3007a (patch) | |
tree | 150075b22836e8271812ee55c5df3a07fc604333 | |
parent | 5c560e90cba7e3955d55a44271faac2a76641c1c (diff) | |
download | mediatek-315852146bd8f190e82f472ec56f5ef411d3007a.tar.gz |
sched/fair: fix race condition between hotplug and sched_group_energy
In case sched_group_energy raced with hotplug, we might enter an infinite
loop, since:
- highest_flag_domain returns NULL
- for_each_domain() loop is never entered
- visit_cpus mask is never cleared
Fix it by simply bailing out if sd is NULL.
Change-Id: I04e89e88cb78d593a6968a5a5e174f1292bfe5ed
Signed-off-by: Juri Lelli <juri.lelli@arm.com>
-rw-r--r-- | kernel/sched/fair.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1c7b5136abf6..925e60327680 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4670,7 +4670,15 @@ static unsigned int sched_group_energy(struct energy_env *eenv) * sched_group? */ sd = highest_flag_domain(cpu, SD_SHARE_CAP_STATES); - if (sd && sd->parent) + if (!sd) + /* + * We most probably raced with hotplug; returning a + * wrong energy estimation is better than entering an + * infinite loop. + */ + break; + + if (sd->parent) sg_shared_cap = sd->parent->groups; for_each_domain(cpu, sd) { |