From f30bdbd035507c07fdd9b88e1f0a9173814ed392 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 17 Nov 2011 11:08:23 -0800 Subject: [PATCH] --- yaml --- r: 277381 b: refs/heads/master c: 77e81365e0b7d7479fc444a21cea0cd4def70b45 h: refs/heads/master i: 277379: 840f86e21c5cbe13d8b71f0151295ff0e9ab3ef7 v: v3 --- [refs] | 2 +- trunk/kernel/sched/fair.c | 38 +++++++++++++++++++++++++------------- trunk/kernel/sched/sched.h | 2 ++ 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/[refs] b/[refs] index 75419c5b9e2b..9c6e72fea6d6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b781a602ac745ee3d5d745276f1e1905a2c101f9 +refs/heads/master: 77e81365e0b7d7479fc444a21cea0cd4def70b45 diff --git a/trunk/kernel/sched/fair.c b/trunk/kernel/sched/fair.c index 7c62e2bf234f..96a9ecec699b 100644 --- a/trunk/kernel/sched/fair.c +++ b/trunk/kernel/sched/fair.c @@ -2644,6 +2644,28 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) return idlest; } +/** + * highest_flag_domain - Return highest sched_domain containing flag. + * @cpu: The cpu whose highest level of sched domain is to + * be returned. + * @flag: The flag to check for the highest sched_domain + * for the given cpu. + * + * Returns the highest sched_domain of a cpu which contains the given flag. + */ +static inline struct sched_domain *highest_flag_domain(int cpu, int flag) +{ + struct sched_domain *sd, *hsd = NULL; + + for_each_domain(cpu, sd) { + if (!(sd->flags & flag)) + break; + hsd = sd; + } + + return hsd; +} + /* * Try and locate an idle CPU in the sched_domain. */ @@ -2653,7 +2675,7 @@ static int select_idle_sibling(struct task_struct *p, int target) int prev_cpu = task_cpu(p); struct sched_domain *sd; struct sched_group *sg; - int i, smt = 0; + int i; /* * If the task is going to be woken-up on this cpu and if it is @@ -2673,19 +2695,9 @@ static int select_idle_sibling(struct task_struct *p, int target) * Otherwise, iterate the domains and find an elegible idle cpu. */ rcu_read_lock(); -again: - for_each_domain(target, sd) { - if (!smt && (sd->flags & SD_SHARE_CPUPOWER)) - continue; - - if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) { - if (!smt) { - smt = 1; - goto again; - } - break; - } + sd = highest_flag_domain(target, SD_SHARE_PKG_RESOURCES); + for_each_lower_domain(sd) { sg = sd->groups; do { if (!cpumask_intersects(sched_group_cpus(sg), diff --git a/trunk/kernel/sched/sched.h b/trunk/kernel/sched/sched.h index c2e780234c31..8715055979d1 100644 --- a/trunk/kernel/sched/sched.h +++ b/trunk/kernel/sched/sched.h @@ -501,6 +501,8 @@ DECLARE_PER_CPU(struct rq, runqueues); #define for_each_domain(cpu, __sd) \ for (__sd = rcu_dereference_check_sched_domain(cpu_rq(cpu)->sd); __sd; __sd = __sd->parent) +#define for_each_lower_domain(sd) for (; sd; sd = sd->child) + #define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) #define this_rq() (&__get_cpu_var(runqueues)) #define task_rq(p) cpu_rq(task_cpu(p))