From: Li Shaohua Make sibling map init per-cpu. Hotplug CPU may change the map at runtime. Signed-off-by: Li Shaohua Signed-off-by: Andrew Morton --- arch/i386/kernel/smpboot.c | 91 ++++++++++++++++++++++++--------------------- 1 files changed, 49 insertions(+), 42 deletions(-) diff -puN arch/i386/kernel/smpboot.c~sibling-map-initializing-rework arch/i386/kernel/smpboot.c --- 25/arch/i386/kernel/smpboot.c~sibling-map-initializing-rework Mon May 9 16:33:33 2005 +++ 25-akpm/arch/i386/kernel/smpboot.c Mon May 9 16:34:10 2005 @@ -63,11 +63,20 @@ static int __initdata smp_b_stepping; /* Number of siblings per CPU package */ int smp_num_siblings = 1; -int phys_proc_id[NR_CPUS] __cacheline_aligned_mostly_readonly; /* Package ID of each logical CPU */ + +/* Package ID of each logical CPU */ +int phys_proc_id[NR_CPUS] __cacheline_aligned_mostly_readonly = + {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(phys_proc_id); -int cpu_core_id[NR_CPUS] __cacheline_aligned_mostly_readonly; /* Core ID of each logical CPU */ + +/* Core ID of each logical CPU */ +int cpu_core_id[NR_CPUS] __cacheline_aligned_mostly_readonly = + {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(cpu_core_id); +cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned_mostly_readonly; +cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned_mostly_readonly; + /* bitmap of online cpus */ cpumask_t cpu_online_map __cacheline_aligned_mostly_readonly; @@ -417,6 +426,38 @@ static void __init smp_callin(void) static int cpucount; +static inline void +set_cpu_sibling_map(int cpu) +{ + int i; + + if (smp_num_siblings > 1) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_isset(i, cpu_callout_map)) + continue; + if (cpu_core_id[cpu] == cpu_core_id[i]) { + cpu_set(i, cpu_sibling_map[cpu]); + cpu_set(cpu, cpu_sibling_map[i]); + } + } + } else { + cpu_set(cpu, cpu_sibling_map[cpu]); + } + + if (current_cpu_data.x86_num_cores > 1) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_isset(i, cpu_callout_map)) + continue; + if (phys_proc_id[cpu] == phys_proc_id[i]) { + cpu_set(i, cpu_core_map[cpu]); + cpu_set(cpu, cpu_core_map[i]); + } + } + } else { + cpu_core_map[cpu] = cpu_sibling_map[cpu]; + } +} + /* * Activate a secondary processor. */ @@ -444,6 +485,10 @@ static void __init start_secondary(void */ local_flush_tlb(); + /* This must be done before setting cpu_online_map */ + set_cpu_sibling_map(_smp_processor_id()); + wmb(); + cpu_set(smp_processor_id(), cpu_online_map); /* We can take interrupts now: we're officially "up". */ @@ -894,9 +939,6 @@ static int boot_cpu_logical_apicid; /* Where the IO area was mapped on multiquad, always 0 otherwise */ void *xquad_portio; -cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned_mostly_readonly; -cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned_mostly_readonly; - static void __init smp_boot_cpus(unsigned int max_cpus) { int apicid, cpu, bit, kicked; @@ -1059,43 +1101,8 @@ static void __init smp_boot_cpus(unsigne cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_core_map[cpu]); } - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - struct cpuinfo_x86 *c = cpu_data + cpu; - int siblings = 0; - int i; - if (!cpu_isset(cpu, cpu_callout_map)) - continue; - - if (smp_num_siblings > 1) { - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_isset(i, cpu_callout_map)) - continue; - if (cpu_core_id[cpu] == cpu_core_id[i]) { - siblings++; - cpu_set(i, cpu_sibling_map[cpu]); - } - } - } else { - siblings++; - cpu_set(cpu, cpu_sibling_map[cpu]); - } - - if (siblings != smp_num_siblings) - printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); - - if (c->x86_num_cores > 1) { - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_isset(i, cpu_callout_map)) - continue; - if (phys_proc_id[cpu] == phys_proc_id[i]) { - cpu_set(i, cpu_core_map[cpu]); - } - } - } else { - cpu_core_map[cpu] = cpu_sibling_map[cpu]; - } - } + cpu_set(0, cpu_sibling_map[0]); + cpu_set(0, cpu_core_map[0]); smpboot_setup_io_apic(); _