|
@@ -6197,7 +6197,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
|
|
static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
|
static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
|
{
|
|
{
|
|
struct sched_domain *sd;
|
|
struct sched_domain *sd;
|
|
- int i;
|
|
|
|
|
|
+ int i, recent_used_cpu;
|
|
|
|
|
|
if (idle_cpu(target))
|
|
if (idle_cpu(target))
|
|
return target;
|
|
return target;
|
|
@@ -6208,6 +6208,21 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
|
if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev))
|
|
if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev))
|
|
return prev;
|
|
return prev;
|
|
|
|
|
|
|
|
+ /* Check a recently used CPU as a potential idle candidate */
|
|
|
|
+ recent_used_cpu = p->recent_used_cpu;
|
|
|
|
+ if (recent_used_cpu != prev &&
|
|
|
|
+ recent_used_cpu != target &&
|
|
|
|
+ cpus_share_cache(recent_used_cpu, target) &&
|
|
|
|
+ idle_cpu(recent_used_cpu) &&
|
|
|
|
+ cpumask_test_cpu(p->recent_used_cpu, &p->cpus_allowed)) {
|
|
|
|
+ /*
|
|
|
|
+ * Replace recent_used_cpu with prev as it is a potential
|
|
|
|
+ * candidate for the next wake.
|
|
|
|
+ */
|
|
|
|
+ p->recent_used_cpu = prev;
|
|
|
|
+ return recent_used_cpu;
|
|
|
|
+ }
|
|
|
|
+
|
|
sd = rcu_dereference(per_cpu(sd_llc, target));
|
|
sd = rcu_dereference(per_cpu(sd_llc, target));
|
|
if (!sd)
|
|
if (!sd)
|
|
return target;
|
|
return target;
|
|
@@ -6375,9 +6390,12 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
|
|
|
|
|
|
if (!sd) {
|
|
if (!sd) {
|
|
pick_cpu:
|
|
pick_cpu:
|
|
- if (sd_flag & SD_BALANCE_WAKE) /* XXX always ? */
|
|
|
|
|
|
+ if (sd_flag & SD_BALANCE_WAKE) { /* XXX always ? */
|
|
new_cpu = select_idle_sibling(p, prev_cpu, new_cpu);
|
|
new_cpu = select_idle_sibling(p, prev_cpu, new_cpu);
|
|
|
|
|
|
|
|
+ if (want_affine)
|
|
|
|
+ current->recent_used_cpu = cpu;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
new_cpu = find_idlest_cpu(sd, p, cpu, prev_cpu, sd_flag);
|
|
new_cpu = find_idlest_cpu(sd, p, cpu, prev_cpu, sd_flag);
|
|
}
|
|
}
|