x86: introduce max_physical_apicid for bigsmp switching
authorYinghai Lu <yhlu.kernel@gmail.com>
Mon, 9 Jun 2008 01:29:22 +0000 (18:29 -0700)
committerIngo Molnar <mingo@elte.hu>
Tue, 10 Jun 2008 09:32:09 +0000 (11:32 +0200)
a multi-socket test-system with 3 or 4 ioapics, when 4 dualcore cpus or
2 quadcore cpus installed, needs to switch to bigsmp or physflat.

CPU apic id is [4,11] instead of [0,7], and we need to check max apic
id instead of cpu numbers.

also add check for 32 bit when acpi is not compiled in or acpi=off.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/apic_32.c
arch/x86/kernel/apic_64.c
arch/x86/kernel/genapic_64.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_32.c
arch/x86/mach-generic/bigsmp.c
include/asm-x86/mpspec.h

index c304759f083442b6574b369b7d7cc8a1e8787d9c..954d67931a504c94c32087aa128d07375f842cee 100644 (file)
@@ -1518,6 +1518,9 @@ void __cpuinit generic_processor_info(int apicid, int version)
                 */
                cpu = 0;
 
+       if (apicid > max_physical_apicid)
+               max_physical_apicid = apicid;
+
        /*
         * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
         * but we need to work other dependencies like SMP_SUSPEND etc
@@ -1525,7 +1528,7 @@ void __cpuinit generic_processor_info(int apicid, int version)
         * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
         *       - Ashok Raj <ashok.raj@intel.com>
         */
-       if (num_processors > 8) {
+       if (max_physical_apicid >= 8) {
                switch (boot_cpu_data.x86_vendor) {
                case X86_VENDOR_INTEL:
                        if (!APIC_XAPIC(version)) {
index 54087f920f2f798f0a179bdfcf280ed4a0046d88..1872555b98a32be8d57d0504d7741852eb24856f 100644 (file)
@@ -1093,6 +1093,9 @@ void __cpuinit generic_processor_info(int apicid, int version)
                 */
                cpu = 0;
        }
+       if (apicid > max_physical_apicid)
+               max_physical_apicid = apicid;
+
        /* are we being called early in kernel startup? */
        if (x86_cpu_to_apicid_early_ptr) {
                u16 *cpu_to_apicid = x86_cpu_to_apicid_early_ptr;
index cbaaf69bedb29c92055e2272a12efba7f49f9ee1..1fa8be5bd217b5c45a649e6745b847567a9553f6 100644 (file)
@@ -51,7 +51,7 @@ void __init setup_apic_routing(void)
        else
 #endif
 
-       if (num_possible_cpus() <= 8)
+       if (max_physical_apicid < 8)
                genapic = &apic_flat;
        else
                genapic = &apic_physflat;
index b4a950da2f97c416b73e0e7d4807fd47e0113ac8..7591325e616d3b90a23a6894b596e69f058b1b9f 100644 (file)
@@ -473,6 +473,11 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
                ++mpc_record;
 #endif
        }
+
+#ifdef CONFIG_X86_GENERICARCH
+       generic_bigsmp_probe();
+#endif
+
        setup_apic_routing();
        if (!num_processors)
                printk(KERN_ERR "MPTABLE: no processors registered!\n");
index 0a281f2c71571ba5a3cde3a00af0f577455769ed..45a5e247d45093af8db7305623e24d9f4a197ba5 100644 (file)
@@ -17,6 +17,7 @@ unsigned int num_processors;
 unsigned disabled_cpus __cpuinitdata;
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
+unsigned int max_physical_apicid;
 EXPORT_SYMBOL(boot_cpu_physical_apicid);
 
 DEFINE_PER_CPU(u16, x86_cpu_to_apicid) = BAD_APICID;
index ee1ccdbd7100967ed3de565254d027cfa7186201..be1a99003677ab36cf4f22bd1a8253137de5eec4 100644 (file)
@@ -838,18 +838,17 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_ACPI
        acpi_boot_init();
-
+#endif
+#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
+       if (smp_found_config)
+               get_smp_config();
+#endif
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
        if (def_to_bigsmp)
                printk(KERN_WARNING "More than 8 CPUs detected and "
                        "CONFIG_X86_PC cannot handle it.\nUse "
                        "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
 #endif
-#endif
-#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
-       if (smp_found_config)
-               get_smp_config();
-#endif
 
        e820_setup_gap();
        e820_mark_nosave_regions(max_low_pfn);
index 95fc463056d0dc92345aaee6cbd0b5ef148add51..2a243019acae830ce08c6688379aa71733c171d3 100644 (file)
@@ -48,7 +48,7 @@ static const struct dmi_system_id bigsmp_dmi_table[] = {
 static int probe_bigsmp(void)
 {
        if (def_to_bigsmp)
-       dmi_bigsmp = 1;
+               dmi_bigsmp = 1;
        else
                dmi_check_system(bigsmp_dmi_table);
        return dmi_bigsmp;
index f38b68e8de5a259b611488efc8b530ade379906e..4451d720ee07b865ebfd2f75014f8763bee4acd9 100644 (file)
@@ -33,6 +33,7 @@ extern int mp_bus_id_to_type[MAX_MP_BUSSES];
 extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 
 extern unsigned int boot_cpu_physical_apicid;
+extern unsigned int max_physical_apicid;
 extern int smp_found_config;
 extern int mpc_default_type;
 extern unsigned long mp_lapic_addr;