|
@@ -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),
|