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 | 90 +++++++++++++++++++++++---------------------- 1 files changed, 47 insertions(+), 43 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 2005-05-26 22:14:21.000000000 -0700 +++ 25-akpm/arch/i386/kernel/smpboot.c 2005-05-26 22:17:43.000000000 -0700 @@ -67,14 +67,21 @@ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); #endif + /* Package ID of each logical CPU */ -int phys_proc_id[NR_CPUS] __cacheline_aligned_mostly_readonly; +int phys_proc_id[NR_CPUS] __cacheline_aligned_mostly_readonly = + {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(phys_proc_id); /* Core ID of each logical CPU */ -int cpu_core_id[NR_CPUS] __cacheline_aligned_mostly_readonly; +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; +EXPORT_SYMBOL(cpu_core_map); + /* bitmap of online cpus */ cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -427,6 +434,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. */ @@ -454,6 +493,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". */ @@ -907,12 +950,9 @@ void *xquad_portio; EXPORT_SYMBOL(xquad_portio); #endif -cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned_mostly_readonly; #ifdef CONFIG_X86_HT EXPORT_SYMBOL(cpu_sibling_map); #endif -cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned_mostly_readonly; -EXPORT_SYMBOL(cpu_core_map); static void __init smp_boot_cpus(unsigned int max_cpus) { @@ -1077,44 +1117,8 @@ static void __init smp_boot_cpus(unsigne 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); - smp_num_siblings = 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(); _