Skip to content

Commit

Permalink
Convert cpu_sibling_map to be a per cpu variable
Browse files Browse the repository at this point in the history
Convert cpu_sibling_map from a static array sized by NR_CPUS to a per_cpu
variable.  This saves sizeof(cpumask_t) * NR unused cpus.  Access is mostly
from startup and CPU HOTPLUG functions.

Signed-off-by: Mike Travis <travis@sgi.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: "Siddha, Suresh B" <suresh.b.siddha@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Mike Travis authored and Linus Torvalds committed Oct 16, 2007
1 parent 0835761 commit d5a7430
Show file tree
Hide file tree
Showing 26 changed files with 107 additions and 82 deletions.
12 changes: 8 additions & 4 deletions arch/ia64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,6 @@ setup_arch (char **cmdline_p)

#ifdef CONFIG_SMP
cpu_physical_id(0) = hard_smp_processor_id();

cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);

check_for_logical_procs();
if (smp_num_cpucores > 1)
printk(KERN_INFO
Expand Down Expand Up @@ -873,6 +869,14 @@ cpu_init (void)
void *cpu_data;

cpu_data = per_cpu_init();
/*
* insert boot cpu into sibling and core mapes
* (must be done after per_cpu area is setup)
*/
if (smp_processor_id() == 0) {
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, cpu_core_map[0]);
}

/*
* We set ar.k3 so that assembly code in MCA handler can compute
Expand Down
18 changes: 10 additions & 8 deletions arch/ia64/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_possible_map);

cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);

int smp_num_siblings = 1;
int smp_num_cpucores = 1;

Expand Down Expand Up @@ -650,12 +652,12 @@ clear_cpu_sibling_map(int cpu)
{
int i;

for_each_cpu_mask(i, cpu_sibling_map[cpu])
cpu_clear(cpu, cpu_sibling_map[i]);
for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
for_each_cpu_mask(i, cpu_core_map[cpu])
cpu_clear(cpu, cpu_core_map[i]);

cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE;
per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE;
}

static void
Expand All @@ -666,7 +668,7 @@ remove_siblinginfo(int cpu)
if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
cpu_clear(cpu, cpu_core_map[cpu]);
cpu_clear(cpu, cpu_sibling_map[cpu]);
cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu));
return;
}

Expand Down Expand Up @@ -807,8 +809,8 @@ set_cpu_sibling_map(int cpu)
cpu_set(i, cpu_core_map[cpu]);
cpu_set(cpu, cpu_core_map[i]);
if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
cpu_set(i, cpu_sibling_map[cpu]);
cpu_set(cpu, cpu_sibling_map[i]);
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
}
}
}
Expand Down Expand Up @@ -839,7 +841,7 @@ __cpu_up (unsigned int cpu)

if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
cpu_set(cpu, cpu_sibling_map[cpu]);
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, cpu_core_map[cpu]);
return 0;
}
Expand Down
20 changes: 16 additions & 4 deletions arch/powerpc/kernel/setup-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,16 +413,28 @@ void __init smp_setup_cpu_maps(void)
of_node_put(dn);
}

vdso_data->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */
}

/*
* Being that cpu_sibling_map is now a per_cpu array, then it cannot
* be initialized until the per_cpu areas have been created. This
* function is now called from setup_per_cpu_areas().
*/
void __init smp_setup_cpu_sibling_map(void)
{
#if defined(CONFIG_PPC64)
int cpu;

/*
* Do the sibling map; assume only two threads per processor.
*/
for_each_possible_cpu(cpu) {
cpu_set(cpu, cpu_sibling_map[cpu]);
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
if (cpu_has_feature(CPU_FTR_SMT))
cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu));
}

vdso_data->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */
}
#endif /* CONFIG_SMP */
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,9 @@ void __init setup_per_cpu_areas(void)
paca[i].data_offset = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
}

/* Now that per_cpu is setup, initialize cpu_sibling_map */
smp_setup_cpu_sibling_map();
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ struct thread_info *secondary_ti;

cpumask_t cpu_possible_map = CPU_MASK_NONE;
cpumask_t cpu_online_map = CPU_MASK_NONE;
cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;

EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
EXPORT_SYMBOL(cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);

/* SMP operations for this machine */
struct smp_ops_t *smp_ops;
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/cell/cbe_cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->cur = cbe_freqs[cur_pmode].frequency;

#ifdef CONFIG_SMP
policy->cpus = cpu_sibling_map[policy->cpu];
policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif

cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
Expand Down
17 changes: 8 additions & 9 deletions arch/sparc64/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,13 @@ int sparc64_multi_core __read_mostly;

cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE;
cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE };
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE };

EXPORT_SYMBOL(cpu_possible_map);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(cpu_core_map);

static cpumask_t smp_commenced_mask;
Expand Down Expand Up @@ -1261,16 +1260,16 @@ void __devinit smp_fill_in_sib_core_maps(void)
for_each_present_cpu(i) {
unsigned int j;

cpus_clear(cpu_sibling_map[i]);
cpus_clear(per_cpu(cpu_sibling_map, i));
if (cpu_data(i).proc_id == -1) {
cpu_set(i, cpu_sibling_map[i]);
cpu_set(i, per_cpu(cpu_sibling_map, i));
continue;
}

for_each_present_cpu(j) {
if (cpu_data(i).proc_id ==
cpu_data(j).proc_id)
cpu_set(j, cpu_sibling_map[i]);
cpu_set(j, per_cpu(cpu_sibling_map, i));
}
}
}
Expand Down Expand Up @@ -1342,9 +1341,9 @@ int __cpu_disable(void)
cpu_clear(cpu, cpu_core_map[i]);
cpus_clear(cpu_core_map[cpu]);

for_each_cpu_mask(i, cpu_sibling_map[cpu])
cpu_clear(cpu, cpu_sibling_map[i]);
cpus_clear(cpu_sibling_map[cpu]);
for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
cpus_clear(per_cpu(cpu_sibling_map, cpu));

c = &cpu_data(cpu);

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
unsigned int i;

#ifdef CONFIG_SMP
policy->cpus = cpu_sibling_map[policy->cpu];
policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif

/* Errata workaround */
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)

/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
policy->cpus = cpu_sibling_map[policy->cpu];
policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif

cpus_allowed = current->cpus_allowed;
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/io_apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ static struct irq_cpu_info {

#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask)

#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i]))
#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))

static cpumask_t balance_irq_affinity[NR_IRQS] = {
[0 ... NR_IRQS-1] = CPU_MASK_ALL
Expand Down Expand Up @@ -598,7 +598,7 @@ static void do_irq_balance(void)
* (A+B)/2 vs B
*/
load = CPU_IRQ(min_loaded) >> 1;
for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) {
for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) {
if (load > CPU_IRQ(j)) {
/* This won't change cpu_sibling_map[min_loaded] */
load = CPU_IRQ(j);
Expand Down
36 changes: 18 additions & 18 deletions arch/x86/kernel/smpboot_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ EXPORT_SYMBOL(smp_num_siblings);
int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};

/* representing HT siblings of each logical CPU */
cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_sibling_map);
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);

/* representing HT and core siblings of each logical CPU */
DEFINE_PER_CPU(cpumask_t, cpu_core_map);
Expand Down Expand Up @@ -319,22 +319,22 @@ void __cpuinit set_cpu_sibling_map(int cpu)
for_each_cpu_mask(i, cpu_sibling_setup_map) {
if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
c[cpu].cpu_core_id == c[i].cpu_core_id) {
cpu_set(i, cpu_sibling_map[cpu]);
cpu_set(cpu, cpu_sibling_map[i]);
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
cpu_set(i, c[cpu].llc_shared_map);
cpu_set(cpu, c[i].llc_shared_map);
}
}
} else {
cpu_set(cpu, cpu_sibling_map[cpu]);
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}

cpu_set(cpu, c[cpu].llc_shared_map);

if (current_cpu_data.x86_max_cores == 1) {
per_cpu(cpu_core_map, cpu) = cpu_sibling_map[cpu];
per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
c[cpu].booted_cores = 1;
return;
}
Expand All @@ -351,12 +351,12 @@ void __cpuinit set_cpu_sibling_map(int cpu)
/*
* Does this new cpu bringup a new core?
*/
if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
/*
* for each core in package, increment
* the booted_cores for this new cpu
*/
if (first_cpu(cpu_sibling_map[i]) == i)
if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
c[cpu].booted_cores++;
/*
* increment the core count for all
Expand Down Expand Up @@ -983,7 +983,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
map_cpu_to_logical_apicid();
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
Expand All @@ -1008,7 +1008,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
Expand All @@ -1023,7 +1023,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
Expand Down Expand Up @@ -1102,15 +1102,15 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
Dprintk("Boot done.\n");

/*
* construct cpu_sibling_map[], so that we can tell sibling CPUs
* construct cpu_sibling_map, so that we can tell sibling CPUs
* efficiently.
*/
for (cpu = 0; cpu < NR_CPUS; cpu++) {
cpus_clear(cpu_sibling_map[cpu]);
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
}

cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));

smpboot_setup_io_apic();
Expand Down Expand Up @@ -1153,13 +1153,13 @@ void remove_siblinginfo(int cpu)
/*/
* last thread sibling in this cpu core going down
*/
if (cpus_weight(cpu_sibling_map[cpu]) == 1)
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
c[sibling].booted_cores--;
}

for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
cpu_clear(cpu, cpu_sibling_map[sibling]);
cpus_clear(cpu_sibling_map[cpu]);
for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
c[cpu].phys_proc_id = 0;
c[cpu].cpu_core_id = 0;
Expand Down
Loading

0 comments on commit d5a7430

Please sign in to comment.