diff options
author | Ingo Molnar <mingo@elte.hu> | 2007-05-02 13:27:04 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:04 -0400 |
commit | 07c7c4744400f93a7c52b32159c31d823e1747a5 (patch) | |
tree | 01e61556711fba606b1e2fbefccb7e2d96a4e0b9 | |
parent | f18d397e6aa5cde638d164b1d519c3ee903f4867 (diff) |
[PATCH] x86-64: always use physical delivery mode on > 8 CPUs
Remove clustered APIC mode. There's little point in the use of clustered APIC
mode, broadcasting is limited to within the cluster only, and chipsets have
bugs in this area as well. So default to physical APIC mode when the CPU
count is large, and default to logical APIC mode when the CPU count is 8 or
smaller.
(this patch only removes the use of genapic_cluster and cleans up the
resulting genapic.c file - removal of all remaining traces of clustered
mode will be done by another patch.)
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: "Li, Shaohua" <shaohua.li@intel.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
-rw-r--r-- | arch/x86_64/kernel/genapic.c | 71 | ||||
-rw-r--r-- | include/asm-x86_64/genapic.h | 4 |
2 files changed, 18 insertions, 57 deletions
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 2f2b8fc6e2f3..025f26ebb8d7 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c | |||
@@ -11,26 +11,24 @@ | |||
11 | #include <linux/threads.h> | 11 | #include <linux/threads.h> |
12 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
17 | #include <linux/module.h> | ||
18 | 18 | ||
19 | #include <asm/smp.h> | 19 | #include <asm/smp.h> |
20 | #include <asm/ipi.h> | 20 | #include <asm/ipi.h> |
21 | 21 | ||
22 | #if defined(CONFIG_ACPI) | 22 | #ifdef CONFIG_ACPI |
23 | #include <acpi/acpi_bus.h> | 23 | #include <acpi/acpi_bus.h> |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | /* which logical CPU number maps to which CPU (physical APIC ID) */ | 26 | /* which logical CPU number maps to which CPU (physical APIC ID) */ |
27 | u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; | 27 | u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly |
28 | = { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
28 | EXPORT_SYMBOL(x86_cpu_to_apicid); | 29 | EXPORT_SYMBOL(x86_cpu_to_apicid); |
29 | u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
30 | 30 | ||
31 | extern struct genapic apic_cluster; | 31 | u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; |
32 | extern struct genapic apic_flat; | ||
33 | extern struct genapic apic_physflat; | ||
34 | 32 | ||
35 | struct genapic __read_mostly *genapic = &apic_flat; | 33 | struct genapic __read_mostly *genapic = &apic_flat; |
36 | 34 | ||
@@ -39,76 +37,37 @@ struct genapic __read_mostly *genapic = &apic_flat; | |||
39 | */ | 37 | */ |
40 | void __init clustered_apic_check(void) | 38 | void __init clustered_apic_check(void) |
41 | { | 39 | { |
42 | int i; | 40 | unsigned int i, max_apic = 0; |
43 | u8 clusters, max_cluster; | ||
44 | u8 id; | 41 | u8 id; |
45 | u8 cluster_cnt[NUM_APIC_CLUSTERS]; | ||
46 | int max_apic = 0; | ||
47 | 42 | ||
48 | #ifdef CONFIG_ACPI | 43 | #ifdef CONFIG_ACPI |
49 | /* | 44 | /* |
50 | * Some x86_64 machines use physical APIC mode regardless of how many | 45 | * Quirk: some x86_64 machines can only use physical APIC mode |
51 | * procs/clusters are present (x86_64 ES7000 is an example). | 46 | * regardless of how many processors are present (x86_64 ES7000 |
47 | * is an example). | ||
52 | */ | 48 | */ |
53 | if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID) | 49 | if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && |
54 | if (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) { | 50 | (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) |
55 | genapic = &apic_cluster; | 51 | genapic = &apic_physflat; |
56 | goto print; | ||
57 | } | ||
58 | #endif | 52 | #endif |
59 | 53 | ||
60 | memset(cluster_cnt, 0, sizeof(cluster_cnt)); | ||
61 | for (i = 0; i < NR_CPUS; i++) { | 54 | for (i = 0; i < NR_CPUS; i++) { |
62 | id = bios_cpu_apicid[i]; | 55 | id = bios_cpu_apicid[i]; |
63 | if (id == BAD_APICID) | 56 | if (id == BAD_APICID) |
64 | continue; | 57 | continue; |
65 | if (id > max_apic) | 58 | if (id > max_apic) |
66 | max_apic = id; | 59 | max_apic = id; |
67 | cluster_cnt[APIC_CLUSTERID(id)]++; | ||
68 | } | 60 | } |
69 | 61 | ||
70 | /* | 62 | if (max_apic < 8) |
71 | * Don't use clustered mode on AMD platforms, default | ||
72 | * to flat logical mode. | ||
73 | */ | ||
74 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | ||
75 | /* | ||
76 | * Switch to physical flat mode if more than 8 APICs | ||
77 | * (In the case of 8 CPUs APIC ID goes from 0 to 7): | ||
78 | */ | ||
79 | if (max_apic >= 8) | ||
80 | genapic = &apic_physflat; | ||
81 | goto print; | ||
82 | } | ||
83 | |||
84 | clusters = 0; | ||
85 | max_cluster = 0; | ||
86 | |||
87 | for (i = 0; i < NUM_APIC_CLUSTERS; i++) { | ||
88 | if (cluster_cnt[i] > 0) { | ||
89 | ++clusters; | ||
90 | if (cluster_cnt[i] > max_cluster) | ||
91 | max_cluster = cluster_cnt[i]; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode, | ||
97 | * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical | ||
98 | * else physical mode. | ||
99 | * (We don't use lowest priority delivery + HW APIC IRQ steering, so | ||
100 | * can ignore the clustered logical case and go straight to physical.) | ||
101 | */ | ||
102 | if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) | ||
103 | genapic = &apic_flat; | 63 | genapic = &apic_flat; |
104 | else | 64 | else |
105 | genapic = &apic_cluster; | 65 | genapic = &apic_physflat; |
106 | 66 | ||
107 | print: | ||
108 | printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); | 67 | printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); |
109 | } | 68 | } |
110 | 69 | ||
111 | /* Same for both flat and clustered. */ | 70 | /* Same for both flat and physical. */ |
112 | 71 | ||
113 | void send_IPI_self(int vector) | 72 | void send_IPI_self(int vector) |
114 | { | 73 | { |
diff --git a/include/asm-x86_64/genapic.h b/include/asm-x86_64/genapic.h index a0e9a4b93484..d7e516ccbaa4 100644 --- a/include/asm-x86_64/genapic.h +++ b/include/asm-x86_64/genapic.h | |||
@@ -29,7 +29,9 @@ struct genapic { | |||
29 | unsigned int (*phys_pkg_id)(int index_msb); | 29 | unsigned int (*phys_pkg_id)(int index_msb); |
30 | }; | 30 | }; |
31 | 31 | ||
32 | |||
33 | extern struct genapic *genapic; | 32 | extern struct genapic *genapic; |
34 | 33 | ||
34 | extern struct genapic apic_flat; | ||
35 | extern struct genapic apic_physflat; | ||
36 | |||
35 | #endif | 37 | #endif |