aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-11-24 11:05:04 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-24 11:50:57 -0500
commit6c99e9ad47d9c082bd096f42fb49e397b05d58a8 (patch)
tree7b0adff66f353b173a3adc05b03b3279bef63c40 /kernel/sched.c
parent758b2cdc6f6a22c702bd8f2344382fb1270b2161 (diff)
sched: convert struct sched_group/sched_domain cpumask_ts to variable bitmaps
Impact: (future) size reduction for large NR_CPUS. We move the 'cpumask' member of sched_group to the end, so when we kmalloc it we can do a minimal allocation: saves space for small nr_cpu_ids but big CONFIG_NR_CPUS. Similar trick for 'span' in sched_domain. This isn't quite as good as converting to a cpumask_var_t, as some sched_groups are actually static, but it's safer: we don't have to figure out where to call alloc_cpumask_var/free_cpumask_var. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 575f38acf4da..6b9606a6cabf 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -7006,18 +7006,33 @@ static void sched_domain_node_span(int node, cpumask_t *span)
7006int sched_smt_power_savings = 0, sched_mc_power_savings = 0; 7006int sched_smt_power_savings = 0, sched_mc_power_savings = 0;
7007 7007
7008/* 7008/*
7009 * The cpus mask in sched_group and sched_domain hangs off the end.
7010 * FIXME: use cpumask_var_t or dynamic percpu alloc to avoid wasting space
7011 * for nr_cpu_ids < CONFIG_NR_CPUS.
7012 */
7013struct static_sched_group {
7014 struct sched_group sg;
7015 DECLARE_BITMAP(cpus, CONFIG_NR_CPUS);
7016};
7017
7018struct static_sched_domain {
7019 struct sched_domain sd;
7020 DECLARE_BITMAP(span, CONFIG_NR_CPUS);
7021};
7022
7023/*
7009 * SMT sched-domains: 7024 * SMT sched-domains:
7010 */ 7025 */
7011#ifdef CONFIG_SCHED_SMT 7026#ifdef CONFIG_SCHED_SMT
7012static DEFINE_PER_CPU(struct sched_domain, cpu_domains); 7027static DEFINE_PER_CPU(struct static_sched_domain, cpu_domains);
7013static DEFINE_PER_CPU(struct sched_group, sched_group_cpus); 7028static DEFINE_PER_CPU(struct static_sched_group, sched_group_cpus);
7014 7029
7015static int 7030static int
7016cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg, 7031cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
7017 cpumask_t *unused) 7032 cpumask_t *unused)
7018{ 7033{
7019 if (sg) 7034 if (sg)
7020 *sg = &per_cpu(sched_group_cpus, cpu); 7035 *sg = &per_cpu(sched_group_cpus, cpu).sg;
7021 return cpu; 7036 return cpu;
7022} 7037}
7023#endif /* CONFIG_SCHED_SMT */ 7038#endif /* CONFIG_SCHED_SMT */
@@ -7026,8 +7041,8 @@ cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
7026 * multi-core sched-domains: 7041 * multi-core sched-domains:
7027 */ 7042 */
7028#ifdef CONFIG_SCHED_MC 7043#ifdef CONFIG_SCHED_MC
7029static DEFINE_PER_CPU(struct sched_domain, core_domains); 7044static DEFINE_PER_CPU(struct static_sched_domain, core_domains);
7030static DEFINE_PER_CPU(struct sched_group, sched_group_core); 7045static DEFINE_PER_CPU(struct static_sched_group, sched_group_core);
7031#endif /* CONFIG_SCHED_MC */ 7046#endif /* CONFIG_SCHED_MC */
7032 7047
7033#if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT) 7048#if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
@@ -7041,7 +7056,7 @@ cpu_to_core_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
7041 cpus_and(*mask, *mask, *cpu_map); 7056 cpus_and(*mask, *mask, *cpu_map);
7042 group = first_cpu(*mask); 7057 group = first_cpu(*mask);
7043 if (sg) 7058 if (sg)
7044 *sg = &per_cpu(sched_group_core, group); 7059 *sg = &per_cpu(sched_group_core, group).sg;
7045 return group; 7060 return group;
7046} 7061}
7047#elif defined(CONFIG_SCHED_MC) 7062#elif defined(CONFIG_SCHED_MC)
@@ -7050,13 +7065,13 @@ cpu_to_core_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
7050 cpumask_t *unused) 7065 cpumask_t *unused)
7051{ 7066{
7052 if (sg) 7067 if (sg)
7053 *sg = &per_cpu(sched_group_core, cpu); 7068 *sg = &per_cpu(sched_group_core, cpu).sg;
7054 return cpu; 7069 return cpu;
7055} 7070}
7056#endif 7071#endif
7057 7072
7058static DEFINE_PER_CPU(struct sched_domain, phys_domains); 7073static DEFINE_PER_CPU(struct static_sched_domain, phys_domains);
7059static DEFINE_PER_CPU(struct sched_group, sched_group_phys); 7074static DEFINE_PER_CPU(struct static_sched_group, sched_group_phys);
7060 7075
7061static int 7076static int
7062cpu_to_phys_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg, 7077cpu_to_phys_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
@@ -7075,7 +7090,7 @@ cpu_to_phys_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
7075 group = cpu; 7090 group = cpu;
7076#endif 7091#endif
7077 if (sg) 7092 if (sg)
7078 *sg = &per_cpu(sched_group_phys, group); 7093 *sg = &per_cpu(sched_group_phys, group).sg;
7079 return group; 7094 return group;
7080} 7095}
7081 7096
@@ -7089,7 +7104,7 @@ static DEFINE_PER_CPU(struct sched_domain, node_domains);
7089static struct sched_group ***sched_group_nodes_bycpu; 7104static struct sched_group ***sched_group_nodes_bycpu;
7090 7105
7091static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); 7106static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
7092static DEFINE_PER_CPU(struct sched_group, sched_group_allnodes); 7107static DEFINE_PER_CPU(struct static_sched_group, sched_group_allnodes);
7093 7108
7094static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map, 7109static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map,
7095 struct sched_group **sg, cpumask_t *nodemask) 7110 struct sched_group **sg, cpumask_t *nodemask)
@@ -7101,7 +7116,7 @@ static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map,
7101 group = first_cpu(*nodemask); 7116 group = first_cpu(*nodemask);
7102 7117
7103 if (sg) 7118 if (sg)
7104 *sg = &per_cpu(sched_group_allnodes, group); 7119 *sg = &per_cpu(sched_group_allnodes, group).sg;
7105 return group; 7120 return group;
7106} 7121}
7107 7122
@@ -7116,7 +7131,7 @@ static void init_numa_sched_groups_power(struct sched_group *group_head)
7116 for_each_cpu(j, sched_group_cpus(sg)) { 7131 for_each_cpu(j, sched_group_cpus(sg)) {
7117 struct sched_domain *sd; 7132 struct sched_domain *sd;
7118 7133
7119 sd = &per_cpu(phys_domains, j); 7134 sd = &per_cpu(phys_domains, j).sd;
7120 if (j != cpumask_first(sched_group_cpus(sd->groups))) { 7135 if (j != cpumask_first(sched_group_cpus(sd->groups))) {
7121 /* 7136 /*
7122 * Only add "power" once for each 7137 * Only add "power" once for each
@@ -7385,7 +7400,7 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7385#endif 7400#endif
7386 7401
7387 p = sd; 7402 p = sd;
7388 sd = &per_cpu(phys_domains, i); 7403 sd = &per_cpu(phys_domains, i).sd;
7389 SD_INIT(sd, CPU); 7404 SD_INIT(sd, CPU);
7390 set_domain_attribute(sd, attr); 7405 set_domain_attribute(sd, attr);
7391 cpumask_copy(sched_domain_span(sd), nodemask); 7406 cpumask_copy(sched_domain_span(sd), nodemask);
@@ -7396,7 +7411,7 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7396 7411
7397#ifdef CONFIG_SCHED_MC 7412#ifdef CONFIG_SCHED_MC
7398 p = sd; 7413 p = sd;
7399 sd = &per_cpu(core_domains, i); 7414 sd = &per_cpu(core_domains, i).sd;
7400 SD_INIT(sd, MC); 7415 SD_INIT(sd, MC);
7401 set_domain_attribute(sd, attr); 7416 set_domain_attribute(sd, attr);
7402 *sched_domain_span(sd) = cpu_coregroup_map(i); 7417 *sched_domain_span(sd) = cpu_coregroup_map(i);
@@ -7409,7 +7424,7 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7409 7424
7410#ifdef CONFIG_SCHED_SMT 7425#ifdef CONFIG_SCHED_SMT
7411 p = sd; 7426 p = sd;
7412 sd = &per_cpu(cpu_domains, i); 7427 sd = &per_cpu(cpu_domains, i).sd;
7413 SD_INIT(sd, SIBLING); 7428 SD_INIT(sd, SIBLING);
7414 set_domain_attribute(sd, attr); 7429 set_domain_attribute(sd, attr);
7415 cpumask_and(sched_domain_span(sd), 7430 cpumask_and(sched_domain_span(sd),
@@ -7485,7 +7500,8 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7485 sched_domain_node_span(i, domainspan); 7500 sched_domain_node_span(i, domainspan);
7486 cpus_and(*domainspan, *domainspan, *cpu_map); 7501 cpus_and(*domainspan, *domainspan, *cpu_map);
7487 7502
7488 sg = kmalloc_node(sizeof(struct sched_group), GFP_KERNEL, i); 7503 sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(),
7504 GFP_KERNEL, i);
7489 if (!sg) { 7505 if (!sg) {
7490 printk(KERN_WARNING "Can not alloc domain group for " 7506 printk(KERN_WARNING "Can not alloc domain group for "
7491 "node %d\n", i); 7507 "node %d\n", i);
@@ -7518,7 +7534,8 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7518 if (cpus_empty(*tmpmask)) 7534 if (cpus_empty(*tmpmask))
7519 continue; 7535 continue;
7520 7536
7521 sg = kmalloc_node(sizeof(struct sched_group), 7537 sg = kmalloc_node(sizeof(struct sched_group) +
7538 cpumask_size(),
7522 GFP_KERNEL, i); 7539 GFP_KERNEL, i);
7523 if (!sg) { 7540 if (!sg) {
7524 printk(KERN_WARNING 7541 printk(KERN_WARNING
@@ -7538,21 +7555,21 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7538 /* Calculate CPU power for physical packages and nodes */ 7555 /* Calculate CPU power for physical packages and nodes */
7539#ifdef CONFIG_SCHED_SMT 7556#ifdef CONFIG_SCHED_SMT
7540 for_each_cpu(i, cpu_map) { 7557 for_each_cpu(i, cpu_map) {
7541 struct sched_domain *sd = &per_cpu(cpu_domains, i); 7558 struct sched_domain *sd = &per_cpu(cpu_domains, i).sd;
7542 7559
7543 init_sched_groups_power(i, sd); 7560 init_sched_groups_power(i, sd);
7544 } 7561 }
7545#endif 7562#endif
7546#ifdef CONFIG_SCHED_MC 7563#ifdef CONFIG_SCHED_MC
7547 for_each_cpu(i, cpu_map) { 7564 for_each_cpu(i, cpu_map) {
7548 struct sched_domain *sd = &per_cpu(core_domains, i); 7565 struct sched_domain *sd = &per_cpu(core_domains, i).sd;
7549 7566
7550 init_sched_groups_power(i, sd); 7567 init_sched_groups_power(i, sd);
7551 } 7568 }
7552#endif 7569#endif
7553 7570
7554 for_each_cpu(i, cpu_map) { 7571 for_each_cpu(i, cpu_map) {
7555 struct sched_domain *sd = &per_cpu(phys_domains, i); 7572 struct sched_domain *sd = &per_cpu(phys_domains, i).sd;
7556 7573
7557 init_sched_groups_power(i, sd); 7574 init_sched_groups_power(i, sd);
7558 } 7575 }
@@ -7574,11 +7591,11 @@ static int __build_sched_domains(const cpumask_t *cpu_map,
7574 for_each_cpu(i, cpu_map) { 7591 for_each_cpu(i, cpu_map) {
7575 struct sched_domain *sd; 7592 struct sched_domain *sd;
7576#ifdef CONFIG_SCHED_SMT 7593#ifdef CONFIG_SCHED_SMT
7577 sd = &per_cpu(cpu_domains, i); 7594 sd = &per_cpu(cpu_domains, i).sd;
7578#elif defined(CONFIG_SCHED_MC) 7595#elif defined(CONFIG_SCHED_MC)
7579 sd = &per_cpu(core_domains, i); 7596 sd = &per_cpu(core_domains, i).sd;
7580#else 7597#else
7581 sd = &per_cpu(phys_domains, i); 7598 sd = &per_cpu(phys_domains, i).sd;
7582#endif 7599#endif
7583 cpu_attach_domain(sd, rd, i); 7600 cpu_attach_domain(sd, rd, i);
7584 } 7601 }