Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318402
b: refs/heads/master
c: 970e178
h: refs/heads/master
v: v3
  • Loading branch information
Mike Galbraith authored and Ingo Molnar committed Jul 24, 2012
1 parent 8e99d7e commit a3aaae2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 23 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: a1cd2b13f754b2c56fb87b8c4912c015f8f57c0c
refs/heads/master: 970e178985cadbca660feb02f4d2ee3a09f7fdda
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ struct sched_domain {
unsigned int smt_gain;
int flags; /* See SD_* */
int level;
int idle_buddy; /* cpu assigned to select_idle_sibling() */

/* Runtime fields. */
unsigned long last_balance; /* init to jiffies. units in jiffies */
Expand Down
39 changes: 38 additions & 1 deletion trunk/kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -6024,6 +6024,11 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu)
* SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this
* allows us to avoid some pointer chasing select_idle_sibling().
*
* Iterate domains and sched_groups downward, assigning CPUs to be
* select_idle_sibling() hw buddy. Cross-wiring hw makes bouncing
* due to random perturbation self canceling, ie sw buddies pull
* their counterpart to their CPU's hw counterpart.
*
* Also keep a unique ID per domain (we use the first cpu number in
* the cpumask of the domain), this allows us to quickly tell if
* two cpus are in the same cache domain, see cpus_share_cache().
Expand All @@ -6037,8 +6042,40 @@ static void update_top_cache_domain(int cpu)
int id = cpu;

sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES);
if (sd)
if (sd) {
struct sched_domain *tmp = sd;
struct sched_group *sg, *prev;
bool right;

/*
* Traverse to first CPU in group, and count hops
* to cpu from there, switching direction on each
* hop, never ever pointing the last CPU rightward.
*/
do {
id = cpumask_first(sched_domain_span(tmp));
prev = sg = tmp->groups;
right = 1;

while (cpumask_first(sched_group_cpus(sg)) != id)
sg = sg->next;

while (!cpumask_test_cpu(cpu, sched_group_cpus(sg))) {
prev = sg;
sg = sg->next;
right = !right;
}

/* A CPU went down, never point back to domain start. */
if (right && cpumask_first(sched_group_cpus(sg->next)) == id)
right = false;

sg = right ? sg->next : prev;
tmp->idle_buddy = cpumask_first(sched_group_cpus(sg));
} while ((tmp = tmp->child));

id = cpumask_first(sched_domain_span(sd));
}

rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);
per_cpu(sd_llc_id, cpu) = id;
Expand Down
28 changes: 7 additions & 21 deletions trunk/kernel/sched/fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -2637,8 +2637,6 @@ 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;
struct sched_group *sg;
int i;

/*
* If the task is going to be woken-up on this cpu and if it is
Expand All @@ -2655,29 +2653,17 @@ static int select_idle_sibling(struct task_struct *p, int target)
return prev_cpu;

/*
* Otherwise, iterate the domains and find an elegible idle cpu.
* Otherwise, check assigned siblings to find an elegible idle cpu.
*/
sd = rcu_dereference(per_cpu(sd_llc, target));
for_each_lower_domain(sd) {
sg = sd->groups;
do {
if (!cpumask_intersects(sched_group_cpus(sg),
tsk_cpus_allowed(p)))
goto next;

for_each_cpu(i, sched_group_cpus(sg)) {
if (!idle_cpu(i))
goto next;
}

target = cpumask_first_and(sched_group_cpus(sg),
tsk_cpus_allowed(p));
goto done;
next:
sg = sg->next;
} while (sg != sd->groups);
for_each_lower_domain(sd) {
if (!cpumask_test_cpu(sd->idle_buddy, tsk_cpus_allowed(p)))
continue;
if (idle_cpu(sd->idle_buddy))
return sd->idle_buddy;
}
done:

return target;
}

Expand Down

0 comments on commit a3aaae2

Please sign in to comment.