Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 191413
b: refs/heads/master
c: 99bd5e2
h: refs/heads/master
i:
  191411: deaf848
v: v3
  • Loading branch information
Suresh Siddha authored and Ingo Molnar committed Apr 23, 2010
1 parent d6ead60 commit d1d2b18
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 669c55e9f99b90e46eaa0f98a67ec53d46dc969a
refs/heads/master: 99bd5e2f245d8cd17d040c82d40becdb3efd9b69
82 changes: 40 additions & 42 deletions trunk/kernel/sched_fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,29 +1375,48 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
/*
* Try and locate an idle CPU in the sched_domain.
*/
static int
select_idle_sibling(struct task_struct *p, struct sched_domain *sd, int target)
static int select_idle_sibling(struct task_struct *p, int target)
{
int cpu = smp_processor_id();
int prev_cpu = task_cpu(p);
struct sched_domain *sd;
int i;

/*
* If this domain spans both cpu and prev_cpu (see the SD_WAKE_AFFINE
* test in select_task_rq_fair) and the prev_cpu is idle then that's
* always a better target than the current cpu.
* If the task is going to be woken-up on this cpu and if it is
* already idle, then it is the right target.
*/
if (target == cpu && idle_cpu(cpu))
return cpu;

/*
* If the task is going to be woken-up on the cpu where it previously
* ran and if it is currently idle, then it the right target.
*/
if (target == cpu && !cpu_rq(prev_cpu)->cfs.nr_running)
if (target == prev_cpu && idle_cpu(prev_cpu))
return prev_cpu;

/*
* Otherwise, iterate the domain and find an elegible idle cpu.
* Otherwise, iterate the domains and find an elegible idle cpu.
*/
for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) {
if (!cpu_rq(i)->cfs.nr_running) {
target = i;
for_each_domain(target, sd) {
if (!(sd->flags & SD_SHARE_PKG_RESOURCES))
break;

for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) {
if (idle_cpu(i)) {
target = i;
break;
}
}

/*
* Lets stop looking for an idle sibling when we reached
* the domain that spans the current cpu and prev_cpu.
*/
if (cpumask_test_cpu(cpu, sched_domain_span(sd)) &&
cpumask_test_cpu(prev_cpu, sched_domain_span(sd)))
break;
}

return target;
Expand All @@ -1421,7 +1440,7 @@ select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_
int cpu = smp_processor_id();
int prev_cpu = task_cpu(p);
int new_cpu = cpu;
int want_affine = 0, cpu_idle = !current->pid;
int want_affine = 0;
int want_sd = 1;
int sync = wake_flags & WF_SYNC;

Expand Down Expand Up @@ -1460,36 +1479,13 @@ select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_
}

/*
* While iterating the domains looking for a spanning
* WAKE_AFFINE domain, adjust the affine target to any idle cpu
* in cache sharing domains along the way.
* If both cpu and prev_cpu are part of this domain,
* cpu is a valid SD_WAKE_AFFINE target.
*/
if (want_affine) {
int target = -1;

/*
* If both cpu and prev_cpu are part of this domain,
* cpu is a valid SD_WAKE_AFFINE target.
*/
if (cpumask_test_cpu(prev_cpu, sched_domain_span(tmp)))
target = cpu;

/*
* If there's an idle sibling in this domain, make that
* the wake_affine target instead of the current cpu.
*/
if (!cpu_idle && tmp->flags & SD_SHARE_PKG_RESOURCES)
target = select_idle_sibling(p, tmp, target);

if (target >= 0) {
if (tmp->flags & SD_WAKE_AFFINE) {
affine_sd = tmp;
want_affine = 0;
if (target != cpu)
cpu_idle = 1;
}
cpu = target;
}
if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
affine_sd = tmp;
want_affine = 0;
}

if (!want_sd && !want_affine)
Expand Down Expand Up @@ -1520,8 +1516,10 @@ select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_
#endif

if (affine_sd) {
if (cpu_idle || cpu == prev_cpu || wake_affine(affine_sd, p, sync))
return cpu;
if (cpu == prev_cpu || wake_affine(affine_sd, p, sync))
return select_idle_sibling(p, cpu);
else
return select_idle_sibling(p, prev_cpu);
}

while (sd) {
Expand Down

0 comments on commit d1d2b18

Please sign in to comment.