aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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: