summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuri Lelli <juri.lelli@arm.com>2015-11-09 15:03:50 +0000
committerTodd Kjos <tkjos@google.com>2015-11-09 16:34:06 -0800
commit315852146bd8f190e82f472ec56f5ef411d3007a (patch)
tree150075b22836e8271812ee55c5df3a07fc604333
parent5c560e90cba7e3955d55a44271faac2a76641c1c (diff)
downloadmediatek-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.c10
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) {