diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/kernel/genapic.c | 39 |
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; | |||
32 | extern struct genapic apic_flat; | 32 | extern struct genapic apic_flat; |
33 | extern struct genapic apic_physflat; | 33 | extern struct genapic apic_physflat; |
34 | 34 | ||
35 | struct genapic *genapic = &apic_flat; | 35 | struct 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 | */ |
41 | void __init clustered_apic_check(void) | 40 | void __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 | ||
116 | print: | 107 | print: |