diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 130 |
1 files changed, 67 insertions, 63 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 52c1953bc41d..c1ce884a0163 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -8246,6 +8246,71 @@ static void init_numa_sched_groups_power(struct sched_group *group_head) | |||
8246 | sg = sg->next; | 8246 | sg = sg->next; |
8247 | } while (sg != group_head); | 8247 | } while (sg != group_head); |
8248 | } | 8248 | } |
8249 | |||
8250 | static int build_numa_sched_groups(struct s_data *d, | ||
8251 | const struct cpumask *cpu_map, int num) | ||
8252 | { | ||
8253 | struct sched_domain *sd; | ||
8254 | struct sched_group *sg, *prev; | ||
8255 | int n, j; | ||
8256 | |||
8257 | cpumask_clear(d->covered); | ||
8258 | cpumask_and(d->nodemask, cpumask_of_node(num), cpu_map); | ||
8259 | if (cpumask_empty(d->nodemask)) { | ||
8260 | d->sched_group_nodes[num] = NULL; | ||
8261 | goto out; | ||
8262 | } | ||
8263 | |||
8264 | sched_domain_node_span(num, d->domainspan); | ||
8265 | cpumask_and(d->domainspan, d->domainspan, cpu_map); | ||
8266 | |||
8267 | sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), | ||
8268 | GFP_KERNEL, num); | ||
8269 | if (!sg) { | ||
8270 | printk(KERN_WARNING "Can not alloc domain group for node %d\n", | ||
8271 | num); | ||
8272 | return -ENOMEM; | ||
8273 | } | ||
8274 | d->sched_group_nodes[num] = sg; | ||
8275 | |||
8276 | for_each_cpu(j, d->nodemask) { | ||
8277 | sd = &per_cpu(node_domains, j).sd; | ||
8278 | sd->groups = sg; | ||
8279 | } | ||
8280 | |||
8281 | sg->__cpu_power = 0; | ||
8282 | cpumask_copy(sched_group_cpus(sg), d->nodemask); | ||
8283 | sg->next = sg; | ||
8284 | cpumask_or(d->covered, d->covered, d->nodemask); | ||
8285 | |||
8286 | prev = sg; | ||
8287 | for (j = 0; j < nr_node_ids; j++) { | ||
8288 | n = (num + j) % nr_node_ids; | ||
8289 | cpumask_complement(d->notcovered, d->covered); | ||
8290 | cpumask_and(d->tmpmask, d->notcovered, cpu_map); | ||
8291 | cpumask_and(d->tmpmask, d->tmpmask, d->domainspan); | ||
8292 | if (cpumask_empty(d->tmpmask)) | ||
8293 | break; | ||
8294 | cpumask_and(d->tmpmask, d->tmpmask, cpumask_of_node(n)); | ||
8295 | if (cpumask_empty(d->tmpmask)) | ||
8296 | continue; | ||
8297 | sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), | ||
8298 | GFP_KERNEL, num); | ||
8299 | if (!sg) { | ||
8300 | printk(KERN_WARNING | ||
8301 | "Can not alloc domain group for node %d\n", j); | ||
8302 | return -ENOMEM; | ||
8303 | } | ||
8304 | sg->__cpu_power = 0; | ||
8305 | cpumask_copy(sched_group_cpus(sg), d->tmpmask); | ||
8306 | sg->next = prev->next; | ||
8307 | cpumask_or(d->covered, d->covered, d->tmpmask); | ||
8308 | prev->next = sg; | ||
8309 | prev = sg; | ||
8310 | } | ||
8311 | out: | ||
8312 | return 0; | ||
8313 | } | ||
8249 | #endif /* CONFIG_NUMA */ | 8314 | #endif /* CONFIG_NUMA */ |
8250 | 8315 | ||
8251 | #ifdef CONFIG_NUMA | 8316 | #ifdef CONFIG_NUMA |
@@ -8652,70 +8717,9 @@ static int __build_sched_domains(const struct cpumask *cpu_map, | |||
8652 | if (d.sd_allnodes) | 8717 | if (d.sd_allnodes) |
8653 | build_sched_groups(&d, SD_LV_ALLNODES, cpu_map, 0); | 8718 | build_sched_groups(&d, SD_LV_ALLNODES, cpu_map, 0); |
8654 | 8719 | ||
8655 | for (i = 0; i < nr_node_ids; i++) { | 8720 | for (i = 0; i < nr_node_ids; i++) |
8656 | /* Set up node groups */ | 8721 | if (build_numa_sched_groups(&d, cpu_map, i)) |
8657 | struct sched_group *sg, *prev; | ||
8658 | int j; | ||
8659 | |||
8660 | cpumask_clear(d.covered); | ||
8661 | cpumask_and(d.nodemask, cpumask_of_node(i), cpu_map); | ||
8662 | if (cpumask_empty(d.nodemask)) { | ||
8663 | d.sched_group_nodes[i] = NULL; | ||
8664 | continue; | ||
8665 | } | ||
8666 | |||
8667 | sched_domain_node_span(i, d.domainspan); | ||
8668 | cpumask_and(d.domainspan, d.domainspan, cpu_map); | ||
8669 | |||
8670 | sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), | ||
8671 | GFP_KERNEL, i); | ||
8672 | if (!sg) { | ||
8673 | printk(KERN_WARNING "Can not alloc domain group for " | ||
8674 | "node %d\n", i); | ||
8675 | goto error; | 8722 | goto error; |
8676 | } | ||
8677 | d.sched_group_nodes[i] = sg; | ||
8678 | for_each_cpu(j, d.nodemask) { | ||
8679 | struct sched_domain *sd; | ||
8680 | |||
8681 | sd = &per_cpu(node_domains, j).sd; | ||
8682 | sd->groups = sg; | ||
8683 | } | ||
8684 | sg->__cpu_power = 0; | ||
8685 | cpumask_copy(sched_group_cpus(sg), d.nodemask); | ||
8686 | sg->next = sg; | ||
8687 | cpumask_or(d.covered, d.covered, d.nodemask); | ||
8688 | prev = sg; | ||
8689 | |||
8690 | for (j = 0; j < nr_node_ids; j++) { | ||
8691 | int n = (i + j) % nr_node_ids; | ||
8692 | |||
8693 | cpumask_complement(d.notcovered, d.covered); | ||
8694 | cpumask_and(d.tmpmask, d.notcovered, cpu_map); | ||
8695 | cpumask_and(d.tmpmask, d.tmpmask, d.domainspan); | ||
8696 | if (cpumask_empty(d.tmpmask)) | ||
8697 | break; | ||
8698 | |||
8699 | cpumask_and(d.tmpmask, d.tmpmask, cpumask_of_node(n)); | ||
8700 | if (cpumask_empty(d.tmpmask)) | ||
8701 | continue; | ||
8702 | |||
8703 | sg = kmalloc_node(sizeof(struct sched_group) + | ||
8704 | cpumask_size(), | ||
8705 | GFP_KERNEL, i); | ||
8706 | if (!sg) { | ||
8707 | printk(KERN_WARNING | ||
8708 | "Can not alloc domain group for node %d\n", j); | ||
8709 | goto error; | ||
8710 | } | ||
8711 | sg->__cpu_power = 0; | ||
8712 | cpumask_copy(sched_group_cpus(sg), d.tmpmask); | ||
8713 | sg->next = prev->next; | ||
8714 | cpumask_or(d.covered, d.covered, d.tmpmask); | ||
8715 | prev->next = sg; | ||
8716 | prev = sg; | ||
8717 | } | ||
8718 | } | ||
8719 | #endif | 8723 | #endif |
8720 | 8724 | ||
8721 | /* Calculate CPU power for physical packages and nodes */ | 8725 | /* Calculate CPU power for physical packages and nodes */ |