aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/genapic.c
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
commitf18d397e6aa5cde638d164b1d519c3ee903f4867 (patch)
tree798794c8aa2599fe7b284a0fc7f7b9b151b18c60 /arch/x86_64/kernel/genapic.c
parenta86f34b49f32b238d16b2e3bf6c9a5391a3f683f (diff)
[PATCH] x86-64: optimize & fix APIC mode setup
Fix a couple of inconsistencies/problems I found while reviewing the x86_64 genapic code (when I was chasing mysterious eth0 timeouts that would only trigger if CPU_HOTPLUG is enabled): - AMD systems defaulted to the slower flat-physical mode instead of the flat-logical mode. The only restriction on AMD systems is that they should not use clustered APIC mode. - removed the CPU hotplug hacks, switching the default for small systems back from phys-flat to logical-flat. The switching to logical flat mode on small systems fixed sporadic ethernet driver timeouts i was getting on a dual-core Athlon64 system: NETDEV WATCHDOG: eth0: transmit timed out eth0: Transmit timeout, status 0c 0005 c07f media 80. eth0: Tx queue start entry 32 dirty entry 28. eth0: Tx descriptor 0 is 0008a04a. (queue head) eth0: Tx descriptor 1 is 0008a04a. eth0: Tx descriptor 2 is 0008a04a. eth0: Tx descriptor 3 is 0008a04a. eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1 - The use of '<= 8' was a bug by itself (the valid APIC ids for logical flat mode go from 0 to 7, not 0 to 8). The new logic is to use logical flat mode on both AMD and Intel systems, and to only switch to physical mode when logical mode cannot be used. If CPU hotplug is racy wrt. APIC shutdown then CPU hotplug needs fixing, not the whole IRQ system be made inconsistent and slowed down. - minor cleanups: simplified some code constructs build & booted on a couple of AMD and Intel SMP systems. 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>
Diffstat (limited to 'arch/x86_64/kernel/genapic.c')
-rw-r--r--arch/x86_64/kernel/genapic.c39
1 files changed, 15 insertions, 24 deletions
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c
index 7312ddb84fb4..2f2b8fc6e2f3 100644
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -32,21 +32,20 @@ extern struct genapic apic_cluster;
32extern struct genapic apic_flat; 32extern struct genapic apic_flat;
33extern struct genapic apic_physflat; 33extern struct genapic apic_physflat;
34 34
35struct genapic *genapic = &apic_flat; 35struct genapic __read_mostly *genapic = &apic_flat;
36
37 36
38/* 37/*
39 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. 38 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
40 */ 39 */
41void __init clustered_apic_check(void) 40void __init clustered_apic_check(void)
42{ 41{
43 long i; 42 int i;
44 u8 clusters, max_cluster; 43 u8 clusters, max_cluster;
45 u8 id; 44 u8 id;
46 u8 cluster_cnt[NUM_APIC_CLUSTERS]; 45 u8 cluster_cnt[NUM_APIC_CLUSTERS];
47 int max_apic = 0; 46 int max_apic = 0;
48 47
49#if defined(CONFIG_ACPI) 48#ifdef CONFIG_ACPI
50 /* 49 /*
51 * Some x86_64 machines use physical APIC mode regardless of how many 50 * Some x86_64 machines use physical APIC mode regardless of how many
52 * procs/clusters are present (x86_64 ES7000 is an example). 51 * procs/clusters are present (x86_64 ES7000 is an example).
@@ -68,20 +67,17 @@ void __init clustered_apic_check(void)
68 cluster_cnt[APIC_CLUSTERID(id)]++; 67 cluster_cnt[APIC_CLUSTERID(id)]++;
69 } 68 }
70 69
71 /* Don't use clustered mode on AMD platforms. */ 70 /*
71 * Don't use clustered mode on AMD platforms, default
72 * to flat logical mode.
73 */
72 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { 74 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
73 genapic = &apic_physflat; 75 /*
74#ifndef CONFIG_HOTPLUG_CPU 76 * Switch to physical flat mode if more than 8 APICs
75 /* In the CPU hotplug case we cannot use broadcast mode 77 * (In the case of 8 CPUs APIC ID goes from 0 to 7):
76 because that opens a race when a CPU is removed. 78 */
77 Stay at physflat mode in this case. 79 if (max_apic >= 8)
78 It is bad to do this unconditionally though. Once 80 genapic = &apic_physflat;
79 we have ACPI platform support for CPU hotplug
80 we should detect hotplug capablity from ACPI tables and
81 only do this when really needed. -AK */
82 if (max_apic <= 8)
83 genapic = &apic_flat;
84#endif
85 goto print; 81 goto print;
86 } 82 }
87 83
@@ -103,14 +99,9 @@ void __init clustered_apic_check(void)
103 * (We don't use lowest priority delivery + HW APIC IRQ steering, so 99 * (We don't use lowest priority delivery + HW APIC IRQ steering, so
104 * can ignore the clustered logical case and go straight to physical.) 100 * can ignore the clustered logical case and go straight to physical.)
105 */ 101 */
106 if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) { 102 if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster)
107#ifdef CONFIG_HOTPLUG_CPU
108 /* Don't use APIC shortcuts in CPU hotplug to avoid races */
109 genapic = &apic_physflat;
110#else
111 genapic = &apic_flat; 103 genapic = &apic_flat;
112#endif 104 else
113 } else
114 genapic = &apic_cluster; 105 genapic = &apic_cluster;
115 106
116print: 107print: