diff options
-rw-r--r-- | include/asm-i386/topology.h | 1 | ||||
-rw-r--r-- | include/asm-ia64/topology.h | 2 | ||||
-rw-r--r-- | include/asm-mips/mach-ip27/topology.h | 1 | ||||
-rw-r--r-- | include/asm-powerpc/topology.h | 1 | ||||
-rw-r--r-- | include/asm-x86_64/topology.h | 1 | ||||
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | include/linux/topology.h | 3 | ||||
-rw-r--r-- | kernel/sched.c | 40 |
8 files changed, 40 insertions, 10 deletions
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index 6adbd9b1ae88..978d09596130 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h | |||
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int node) | |||
74 | #define SD_NODE_INIT (struct sched_domain) { \ | 74 | #define SD_NODE_INIT (struct sched_domain) { \ |
75 | .span = CPU_MASK_NONE, \ | 75 | .span = CPU_MASK_NONE, \ |
76 | .parent = NULL, \ | 76 | .parent = NULL, \ |
77 | .child = NULL, \ | ||
77 | .groups = NULL, \ | 78 | .groups = NULL, \ |
78 | .min_interval = 8, \ | 79 | .min_interval = 8, \ |
79 | .max_interval = 32, \ | 80 | .max_interval = 32, \ |
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index 937c21257523..a6e38565ab4c 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h | |||
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void); | |||
59 | #define SD_CPU_INIT (struct sched_domain) { \ | 59 | #define SD_CPU_INIT (struct sched_domain) { \ |
60 | .span = CPU_MASK_NONE, \ | 60 | .span = CPU_MASK_NONE, \ |
61 | .parent = NULL, \ | 61 | .parent = NULL, \ |
62 | .child = NULL, \ | ||
62 | .groups = NULL, \ | 63 | .groups = NULL, \ |
63 | .min_interval = 1, \ | 64 | .min_interval = 1, \ |
64 | .max_interval = 4, \ | 65 | .max_interval = 4, \ |
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void); | |||
84 | #define SD_NODE_INIT (struct sched_domain) { \ | 85 | #define SD_NODE_INIT (struct sched_domain) { \ |
85 | .span = CPU_MASK_NONE, \ | 86 | .span = CPU_MASK_NONE, \ |
86 | .parent = NULL, \ | 87 | .parent = NULL, \ |
88 | .child = NULL, \ | ||
87 | .groups = NULL, \ | 89 | .groups = NULL, \ |
88 | .min_interval = 8, \ | 90 | .min_interval = 8, \ |
89 | .max_interval = 8*(min(num_online_cpus(), 32)), \ | 91 | .max_interval = 8*(min(num_online_cpus(), 32)), \ |
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h index 59d26b52ba32..a13b715fd9ca 100644 --- a/include/asm-mips/mach-ip27/topology.h +++ b/include/asm-mips/mach-ip27/topology.h | |||
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; | |||
22 | #define SD_NODE_INIT (struct sched_domain) { \ | 22 | #define SD_NODE_INIT (struct sched_domain) { \ |
23 | .span = CPU_MASK_NONE, \ | 23 | .span = CPU_MASK_NONE, \ |
24 | .parent = NULL, \ | 24 | .parent = NULL, \ |
25 | .child = NULL, \ | ||
25 | .groups = NULL, \ | 26 | .groups = NULL, \ |
26 | .min_interval = 8, \ | 27 | .min_interval = 8, \ |
27 | .max_interval = 32, \ | 28 | .max_interval = 32, \ |
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h index bbc3844b086f..8f7ee16781a4 100644 --- a/include/asm-powerpc/topology.h +++ b/include/asm-powerpc/topology.h | |||
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus *bus); | |||
43 | #define SD_NODE_INIT (struct sched_domain) { \ | 43 | #define SD_NODE_INIT (struct sched_domain) { \ |
44 | .span = CPU_MASK_NONE, \ | 44 | .span = CPU_MASK_NONE, \ |
45 | .parent = NULL, \ | 45 | .parent = NULL, \ |
46 | .child = NULL, \ | ||
46 | .groups = NULL, \ | 47 | .groups = NULL, \ |
47 | .min_interval = 8, \ | 48 | .min_interval = 8, \ |
48 | .max_interval = 32, \ | 49 | .max_interval = 32, \ |
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index 6e7a2e976b04..5c8f49280dbc 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h | |||
@@ -31,6 +31,7 @@ extern int __node_distance(int, int); | |||
31 | #define SD_NODE_INIT (struct sched_domain) { \ | 31 | #define SD_NODE_INIT (struct sched_domain) { \ |
32 | .span = CPU_MASK_NONE, \ | 32 | .span = CPU_MASK_NONE, \ |
33 | .parent = NULL, \ | 33 | .parent = NULL, \ |
34 | .child = NULL, \ | ||
34 | .groups = NULL, \ | 35 | .groups = NULL, \ |
35 | .min_interval = 8, \ | 36 | .min_interval = 8, \ |
36 | .max_interval = 32, \ | 37 | .max_interval = 32, \ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 38530232d92f..8e26c9069f15 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -644,6 +644,7 @@ struct sched_group { | |||
644 | struct sched_domain { | 644 | struct sched_domain { |
645 | /* These fields must be setup */ | 645 | /* These fields must be setup */ |
646 | struct sched_domain *parent; /* top domain must be null terminated */ | 646 | struct sched_domain *parent; /* top domain must be null terminated */ |
647 | struct sched_domain *child; /* bottom domain must be null terminated */ | ||
647 | struct sched_group *groups; /* the balancing groups of the domain */ | 648 | struct sched_group *groups; /* the balancing groups of the domain */ |
648 | cpumask_t span; /* span of all CPUs in this domain */ | 649 | cpumask_t span; /* span of all CPUs in this domain */ |
649 | unsigned long min_interval; /* Minimum balance interval ms */ | 650 | unsigned long min_interval; /* Minimum balance interval ms */ |
diff --git a/include/linux/topology.h b/include/linux/topology.h index ec1eca85290a..486bec23f986 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h | |||
@@ -89,6 +89,7 @@ | |||
89 | #define SD_SIBLING_INIT (struct sched_domain) { \ | 89 | #define SD_SIBLING_INIT (struct sched_domain) { \ |
90 | .span = CPU_MASK_NONE, \ | 90 | .span = CPU_MASK_NONE, \ |
91 | .parent = NULL, \ | 91 | .parent = NULL, \ |
92 | .child = NULL, \ | ||
92 | .groups = NULL, \ | 93 | .groups = NULL, \ |
93 | .min_interval = 1, \ | 94 | .min_interval = 1, \ |
94 | .max_interval = 2, \ | 95 | .max_interval = 2, \ |
@@ -119,6 +120,7 @@ | |||
119 | #define SD_CPU_INIT (struct sched_domain) { \ | 120 | #define SD_CPU_INIT (struct sched_domain) { \ |
120 | .span = CPU_MASK_NONE, \ | 121 | .span = CPU_MASK_NONE, \ |
121 | .parent = NULL, \ | 122 | .parent = NULL, \ |
123 | .child = NULL, \ | ||
122 | .groups = NULL, \ | 124 | .groups = NULL, \ |
123 | .min_interval = 1, \ | 125 | .min_interval = 1, \ |
124 | .max_interval = 4, \ | 126 | .max_interval = 4, \ |
@@ -146,6 +148,7 @@ | |||
146 | #define SD_ALLNODES_INIT (struct sched_domain) { \ | 148 | #define SD_ALLNODES_INIT (struct sched_domain) { \ |
147 | .span = CPU_MASK_NONE, \ | 149 | .span = CPU_MASK_NONE, \ |
148 | .parent = NULL, \ | 150 | .parent = NULL, \ |
151 | .child = NULL, \ | ||
149 | .groups = NULL, \ | 152 | .groups = NULL, \ |
150 | .min_interval = 64, \ | 153 | .min_interval = 64, \ |
151 | .max_interval = 64*num_online_cpus(), \ | 154 | .max_interval = 64*num_online_cpus(), \ |
diff --git a/kernel/sched.c b/kernel/sched.c index 6d7bf55ec33d..0feeacb91497 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -1286,21 +1286,29 @@ static int sched_balance_self(int cpu, int flag) | |||
1286 | while (sd) { | 1286 | while (sd) { |
1287 | cpumask_t span; | 1287 | cpumask_t span; |
1288 | struct sched_group *group; | 1288 | struct sched_group *group; |
1289 | int new_cpu; | 1289 | int new_cpu, weight; |
1290 | int weight; | 1290 | |
1291 | if (!(sd->flags & flag)) { | ||
1292 | sd = sd->child; | ||
1293 | continue; | ||
1294 | } | ||
1291 | 1295 | ||
1292 | span = sd->span; | 1296 | span = sd->span; |
1293 | group = find_idlest_group(sd, t, cpu); | 1297 | group = find_idlest_group(sd, t, cpu); |
1294 | if (!group) | 1298 | if (!group) { |
1295 | goto nextlevel; | 1299 | sd = sd->child; |
1300 | continue; | ||
1301 | } | ||
1296 | 1302 | ||
1297 | new_cpu = find_idlest_cpu(group, t, cpu); | 1303 | new_cpu = find_idlest_cpu(group, t, cpu); |
1298 | if (new_cpu == -1 || new_cpu == cpu) | 1304 | if (new_cpu == -1 || new_cpu == cpu) { |
1299 | goto nextlevel; | 1305 | /* Now try balancing at a lower domain level of cpu */ |
1306 | sd = sd->child; | ||
1307 | continue; | ||
1308 | } | ||
1300 | 1309 | ||
1301 | /* Now try balancing at a lower domain level */ | 1310 | /* Now try balancing at a lower domain level of new_cpu */ |
1302 | cpu = new_cpu; | 1311 | cpu = new_cpu; |
1303 | nextlevel: | ||
1304 | sd = NULL; | 1312 | sd = NULL; |
1305 | weight = cpus_weight(span); | 1313 | weight = cpus_weight(span); |
1306 | for_each_domain(cpu, tmp) { | 1314 | for_each_domain(cpu, tmp) { |
@@ -5448,12 +5456,18 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu) | |||
5448 | struct sched_domain *parent = tmp->parent; | 5456 | struct sched_domain *parent = tmp->parent; |
5449 | if (!parent) | 5457 | if (!parent) |
5450 | break; | 5458 | break; |
5451 | if (sd_parent_degenerate(tmp, parent)) | 5459 | if (sd_parent_degenerate(tmp, parent)) { |
5452 | tmp->parent = parent->parent; | 5460 | tmp->parent = parent->parent; |
5461 | if (parent->parent) | ||
5462 | parent->parent->child = tmp; | ||
5463 | } | ||
5453 | } | 5464 | } |
5454 | 5465 | ||
5455 | if (sd && sd_degenerate(sd)) | 5466 | if (sd && sd_degenerate(sd)) { |
5456 | sd = sd->parent; | 5467 | sd = sd->parent; |
5468 | if (sd) | ||
5469 | sd->child = NULL; | ||
5470 | } | ||
5457 | 5471 | ||
5458 | sched_domain_debug(sd, cpu); | 5472 | sched_domain_debug(sd, cpu); |
5459 | 5473 | ||
@@ -6288,6 +6302,8 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6288 | *sd = SD_NODE_INIT; | 6302 | *sd = SD_NODE_INIT; |
6289 | sd->span = sched_domain_node_span(cpu_to_node(i)); | 6303 | sd->span = sched_domain_node_span(cpu_to_node(i)); |
6290 | sd->parent = p; | 6304 | sd->parent = p; |
6305 | if (p) | ||
6306 | p->child = sd; | ||
6291 | cpus_and(sd->span, sd->span, *cpu_map); | 6307 | cpus_and(sd->span, sd->span, *cpu_map); |
6292 | #endif | 6308 | #endif |
6293 | 6309 | ||
@@ -6297,6 +6313,8 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6297 | *sd = SD_CPU_INIT; | 6313 | *sd = SD_CPU_INIT; |
6298 | sd->span = nodemask; | 6314 | sd->span = nodemask; |
6299 | sd->parent = p; | 6315 | sd->parent = p; |
6316 | if (p) | ||
6317 | p->child = sd; | ||
6300 | sd->groups = &sched_group_phys[group]; | 6318 | sd->groups = &sched_group_phys[group]; |
6301 | 6319 | ||
6302 | #ifdef CONFIG_SCHED_MC | 6320 | #ifdef CONFIG_SCHED_MC |
@@ -6307,6 +6325,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6307 | sd->span = cpu_coregroup_map(i); | 6325 | sd->span = cpu_coregroup_map(i); |
6308 | cpus_and(sd->span, sd->span, *cpu_map); | 6326 | cpus_and(sd->span, sd->span, *cpu_map); |
6309 | sd->parent = p; | 6327 | sd->parent = p; |
6328 | p->child = sd; | ||
6310 | sd->groups = &sched_group_core[group]; | 6329 | sd->groups = &sched_group_core[group]; |
6311 | #endif | 6330 | #endif |
6312 | 6331 | ||
@@ -6318,6 +6337,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6318 | sd->span = cpu_sibling_map[i]; | 6337 | sd->span = cpu_sibling_map[i]; |
6319 | cpus_and(sd->span, sd->span, *cpu_map); | 6338 | cpus_and(sd->span, sd->span, *cpu_map); |
6320 | sd->parent = p; | 6339 | sd->parent = p; |
6340 | p->child = sd; | ||
6321 | sd->groups = &sched_group_cpus[group]; | 6341 | sd->groups = &sched_group_cpus[group]; |
6322 | #endif | 6342 | #endif |
6323 | } | 6343 | } |