aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2007-05-02 13:27:04 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:04 -0400
commit07c7c4744400f93a7c52b32159c31d823e1747a5 (patch)
tree01e61556711fba606b1e2fbefccb7e2d96a4e0b9
parentf18d397e6aa5cde638d164b1d519c3ee903f4867 (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.c71
-rw-r--r--include/asm-x86_64/genapic.h4
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) */
27u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; 27u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
28 = { [0 ... NR_CPUS-1] = BAD_APICID };
28EXPORT_SYMBOL(x86_cpu_to_apicid); 29EXPORT_SYMBOL(x86_cpu_to_apicid);
29u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
30 30
31extern struct genapic apic_cluster; 31u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
32extern struct genapic apic_flat;
33extern struct genapic apic_physflat;
34 32
35struct genapic __read_mostly *genapic = &apic_flat; 33struct genapic __read_mostly *genapic = &apic_flat;
36 34
@@ -39,76 +37,37 @@ struct genapic __read_mostly *genapic = &apic_flat;
39 */ 37 */
40void __init clustered_apic_check(void) 38void __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
107print:
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
113void send_IPI_self(int vector) 72void 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
33extern struct genapic *genapic; 32extern struct genapic *genapic;
34 33
34extern struct genapic apic_flat;
35extern struct genapic apic_physflat;
36
35#endif 37#endif