diff options
author | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 2005-09-03 18:56:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:10 -0400 |
commit | 911a62d42365076209e2c327e7688db296e35d62 (patch) | |
tree | 51e6d8525cd3547ea43129b5dd20339655674d57 | |
parent | 484b90c4b965d54037ff99b198d84cdf144f8a35 (diff) |
[PATCH] x86: sutomatically enable bigsmp when we have more than 8 CPUs
i386 generic subarchitecture requires explicit dmi strings or command line
to enable bigsmp mode. The patch below removes that restriction, and uses
bigsmp as soon as it finds more than 8 logical CPUs, Intel processors and
xAPIC support.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/mpparse.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/i386/mach-generic/bigsmp.c | 5 | ||||
-rw-r--r-- | arch/i386/mach-generic/probe.c | 20 | ||||
-rw-r--r-- | include/asm-i386/apicdef.h | 1 | ||||
-rw-r--r-- | include/asm-i386/mach-generic/mach_apic.h | 2 | ||||
-rw-r--r-- | include/asm-i386/mpspec.h | 1 |
8 files changed, 47 insertions, 2 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index b7808a89d945..34ee500c26e5 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -833,6 +833,9 @@ acpi_process_madt(void) | |||
833 | if (!error) { | 833 | if (!error) { |
834 | acpi_lapic = 1; | 834 | acpi_lapic = 1; |
835 | 835 | ||
836 | #ifdef CONFIG_X86_GENERICARCH | ||
837 | generic_bigsmp_probe(); | ||
838 | #endif | ||
836 | /* | 839 | /* |
837 | * Parse MADT IO-APIC entries | 840 | * Parse MADT IO-APIC entries |
838 | */ | 841 | */ |
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index ce838abb27d8..788efffa9930 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -65,6 +65,8 @@ int nr_ioapics; | |||
65 | int pic_mode; | 65 | int pic_mode; |
66 | unsigned long mp_lapic_addr; | 66 | unsigned long mp_lapic_addr; |
67 | 67 | ||
68 | unsigned int def_to_bigsmp = 0; | ||
69 | |||
68 | /* Processor that is doing the boot up */ | 70 | /* Processor that is doing the boot up */ |
69 | unsigned int boot_cpu_physical_apicid = -1U; | 71 | unsigned int boot_cpu_physical_apicid = -1U; |
70 | /* Internal processor count */ | 72 | /* Internal processor count */ |
@@ -213,6 +215,13 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
213 | ver = 0x10; | 215 | ver = 0x10; |
214 | } | 216 | } |
215 | apic_version[m->mpc_apicid] = ver; | 217 | apic_version[m->mpc_apicid] = ver; |
218 | if ((num_processors > 8) && | ||
219 | APIC_XAPIC(ver) && | ||
220 | (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) | ||
221 | def_to_bigsmp = 1; | ||
222 | else | ||
223 | def_to_bigsmp = 0; | ||
224 | |||
216 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; | 225 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; |
217 | } | 226 | } |
218 | 227 | ||
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 9adbf710ec8d..294bcca985ab 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -1585,8 +1585,14 @@ void __init setup_arch(char **cmdline_p) | |||
1585 | */ | 1585 | */ |
1586 | acpi_boot_table_init(); | 1586 | acpi_boot_table_init(); |
1587 | acpi_boot_init(); | 1587 | acpi_boot_init(); |
1588 | #endif | ||
1589 | 1588 | ||
1589 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) | ||
1590 | if (def_to_bigsmp) | ||
1591 | printk(KERN_WARNING "More than 8 CPUs detected and " | ||
1592 | "CONFIG_X86_PC cannot handle it.\nUse " | ||
1593 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); | ||
1594 | #endif | ||
1595 | #endif | ||
1590 | #ifdef CONFIG_X86_LOCAL_APIC | 1596 | #ifdef CONFIG_X86_LOCAL_APIC |
1591 | if (smp_found_config) | 1597 | if (smp_found_config) |
1592 | get_smp_config(); | 1598 | get_smp_config(); |
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index 25883b44f625..037b2af1a1f4 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c | |||
@@ -47,7 +47,10 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { | |||
47 | 47 | ||
48 | static __init int probe_bigsmp(void) | 48 | static __init int probe_bigsmp(void) |
49 | { | 49 | { |
50 | dmi_check_system(bigsmp_dmi_table); | 50 | if (def_to_bigsmp) |
51 | dmi_bigsmp = 1; | ||
52 | else | ||
53 | dmi_check_system(bigsmp_dmi_table); | ||
51 | return dmi_bigsmp; | 54 | return dmi_bigsmp; |
52 | } | 55 | } |
53 | 56 | ||
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index 5497c65a8790..cea5b3ce4b57 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c | |||
@@ -30,6 +30,25 @@ struct genapic *apic_probe[] __initdata = { | |||
30 | NULL, | 30 | NULL, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static int cmdline_apic; | ||
34 | |||
35 | void __init generic_bigsmp_probe(void) | ||
36 | { | ||
37 | /* | ||
38 | * This routine is used to switch to bigsmp mode when | ||
39 | * - There is no apic= option specified by the user | ||
40 | * - generic_apic_probe() has choosen apic_default as the sub_arch | ||
41 | * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support | ||
42 | */ | ||
43 | |||
44 | if (!cmdline_apic && genapic == &apic_default) | ||
45 | if (apic_bigsmp.probe()) { | ||
46 | genapic = &apic_bigsmp; | ||
47 | printk(KERN_INFO "Overriding APIC driver with %s\n", | ||
48 | genapic->name); | ||
49 | } | ||
50 | } | ||
51 | |||
33 | void __init generic_apic_probe(char *command_line) | 52 | void __init generic_apic_probe(char *command_line) |
34 | { | 53 | { |
35 | char *s; | 54 | char *s; |
@@ -52,6 +71,7 @@ void __init generic_apic_probe(char *command_line) | |||
52 | if (!changed) | 71 | if (!changed) |
53 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); | 72 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); |
54 | *p = old; | 73 | *p = old; |
74 | cmdline_apic = changed; | ||
55 | } | 75 | } |
56 | for (i = 0; !changed && apic_probe[i]; i++) { | 76 | for (i = 0; !changed && apic_probe[i]; i++) { |
57 | if (apic_probe[i]->probe()) { | 77 | if (apic_probe[i]->probe()) { |
diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h index a96a8f48fbfc..03185cef8e0a 100644 --- a/include/asm-i386/apicdef.h +++ b/include/asm-i386/apicdef.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define GET_APIC_VERSION(x) ((x)&0xFF) | 16 | #define GET_APIC_VERSION(x) ((x)&0xFF) |
17 | #define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF) | 17 | #define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF) |
18 | #define APIC_INTEGRATED(x) ((x)&0xF0) | 18 | #define APIC_INTEGRATED(x) ((x)&0xF0) |
19 | #define APIC_XAPIC(x) ((x) >= 0x14) | ||
19 | #define APIC_TASKPRI 0x80 | 20 | #define APIC_TASKPRI 0x80 |
20 | #define APIC_TPRI_MASK 0xFF | 21 | #define APIC_TPRI_MASK 0xFF |
21 | #define APIC_ARBPRI 0x90 | 22 | #define APIC_ARBPRI 0x90 |
diff --git a/include/asm-i386/mach-generic/mach_apic.h b/include/asm-i386/mach-generic/mach_apic.h index b13767a4e934..d9dc039da94a 100644 --- a/include/asm-i386/mach-generic/mach_apic.h +++ b/include/asm-i386/mach-generic/mach_apic.h | |||
@@ -28,4 +28,6 @@ | |||
28 | #define enable_apic_mode (genapic->enable_apic_mode) | 28 | #define enable_apic_mode (genapic->enable_apic_mode) |
29 | #define phys_pkg_id (genapic->phys_pkg_id) | 29 | #define phys_pkg_id (genapic->phys_pkg_id) |
30 | 30 | ||
31 | extern void generic_bigsmp_probe(void); | ||
32 | |||
31 | #endif /* __ASM_MACH_APIC_H */ | 33 | #endif /* __ASM_MACH_APIC_H */ |
diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index d9fafba075bc..d84a9c326c22 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h | |||
@@ -11,6 +11,7 @@ extern int mp_bus_id_to_local [MAX_MP_BUSSES]; | |||
11 | extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; | 11 | extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; |
12 | extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; | 12 | extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; |
13 | 13 | ||
14 | extern unsigned int def_to_bigsmp; | ||
14 | extern unsigned int boot_cpu_physical_apicid; | 15 | extern unsigned int boot_cpu_physical_apicid; |
15 | extern int smp_found_config; | 16 | extern int smp_found_config; |
16 | extern void find_smp_config (void); | 17 | extern void find_smp_config (void); |