aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_core.c
diff options
context:
space:
mode:
authorGu Zheng <guz.fnst@cn.fujitsu.com>2016-08-25 04:35:17 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-21 15:18:39 -0400
commit8ad893faf2eaedb710a3073afbb5d569df2c3e41 (patch)
treeac488564d4d25f82fbcb5e6a8f331a3eb2401b34 /drivers/acpi/processor_core.c
parent8f54969dc8d6704632b42cbb5e47730cd75cc713 (diff)
x86/acpi: Enable MADT APIs to return disabled apicids
The whole patch-set aims at making cpuid <-> nodeid mapping persistent. So that, when node online/offline happens, cache based on cpuid <-> nodeid mapping such as wq_numa_possible_cpumask will not cause any problem. It contains 4 steps: 1. Enable apic registeration flow to handle both enabled and disabled cpus. 2. Introduce a new array storing all possible cpuid <-> apicid mapping. 3. Enable _MAT and MADT relative apis to return non-present or disabled cpus' apicid. 4. Establish all possible cpuid <-> nodeid mapping. This patch finishes step 3. There are four mappings in the kernel: 1. nodeid (logical node id) <-> pxm (persistent) 2. apicid (physical cpu id) <-> nodeid (persistent) 3. cpuid (logical cpu id) <-> apicid (not persistent, now persistent by step 2) 4. cpuid (logical cpu id) <-> nodeid (not persistent) So, in order to setup persistent cpuid <-> nodeid mapping for all possible CPUs, we should: 1. Setup cpuid <-> apicid mapping for all possible CPUs, which has been done in step 1, 2. 2. Setup cpuid <-> nodeid mapping for all possible CPUs. But before that, we should obtain all apicids from MADT. All processors' apicids can be obtained by _MAT method or from MADT in ACPI. The current code ignores disabled processors and returns -ENODEV. After this patch, a new parameter will be added to MADT APIs so that caller is able to control if disabled processors are ignored. Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com> Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Signed-off-by: Zhu Guihua <zhugh.fnst@cn.fujitsu.com> Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: mika.j.penttila@gmail.com Cc: len.brown@intel.com Cc: rafael@kernel.org Cc: rjw@rjwysocki.net Cc: yasu.isimatu@gmail.com Cc: linux-mm@kvack.org Cc: linux-acpi@vger.kernel.org Cc: isimatu.yasuaki@jp.fujitsu.com Cc: gongzhaogang@inspur.com Cc: tj@kernel.org Cc: izumi.taku@jp.fujitsu.com Cc: cl@linux.com Cc: chen.tang@easystack.cn Cc: akpm@linux-foundation.org Cc: kamezawa.hiroyu@jp.fujitsu.com Cc: lenb@kernel.org Link: http://lkml.kernel.org/r/1472114120-3281-5-git-send-email-douly.fnst@cn.fujitsu.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/acpi/processor_core.c')
-rw-r--r--drivers/acpi/processor_core.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9125d7d96372..fd59ae871db3 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -32,12 +32,12 @@ static struct acpi_table_madt *get_madt_table(void)
32} 32}
33 33
34static int map_lapic_id(struct acpi_subtable_header *entry, 34static int map_lapic_id(struct acpi_subtable_header *entry,
35 u32 acpi_id, phys_cpuid_t *apic_id) 35 u32 acpi_id, phys_cpuid_t *apic_id, bool ignore_disabled)
36{ 36{
37 struct acpi_madt_local_apic *lapic = 37 struct acpi_madt_local_apic *lapic =
38 container_of(entry, struct acpi_madt_local_apic, header); 38 container_of(entry, struct acpi_madt_local_apic, header);
39 39
40 if (!(lapic->lapic_flags & ACPI_MADT_ENABLED)) 40 if (ignore_disabled && !(lapic->lapic_flags & ACPI_MADT_ENABLED))
41 return -ENODEV; 41 return -ENODEV;
42 42
43 if (lapic->processor_id != acpi_id) 43 if (lapic->processor_id != acpi_id)
@@ -48,12 +48,13 @@ static int map_lapic_id(struct acpi_subtable_header *entry,
48} 48}
49 49
50static int map_x2apic_id(struct acpi_subtable_header *entry, 50static int map_x2apic_id(struct acpi_subtable_header *entry,
51 int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id) 51 int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id,
52 bool ignore_disabled)
52{ 53{
53 struct acpi_madt_local_x2apic *apic = 54 struct acpi_madt_local_x2apic *apic =
54 container_of(entry, struct acpi_madt_local_x2apic, header); 55 container_of(entry, struct acpi_madt_local_x2apic, header);
55 56
56 if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) 57 if (ignore_disabled && !(apic->lapic_flags & ACPI_MADT_ENABLED))
57 return -ENODEV; 58 return -ENODEV;
58 59
59 if (device_declaration && (apic->uid == acpi_id)) { 60 if (device_declaration && (apic->uid == acpi_id)) {
@@ -65,12 +66,13 @@ static int map_x2apic_id(struct acpi_subtable_header *entry,
65} 66}
66 67
67static int map_lsapic_id(struct acpi_subtable_header *entry, 68static int map_lsapic_id(struct acpi_subtable_header *entry,
68 int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id) 69 int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id,
70 bool ignore_disabled)
69{ 71{
70 struct acpi_madt_local_sapic *lsapic = 72 struct acpi_madt_local_sapic *lsapic =
71 container_of(entry, struct acpi_madt_local_sapic, header); 73 container_of(entry, struct acpi_madt_local_sapic, header);
72 74
73 if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) 75 if (ignore_disabled && !(lsapic->lapic_flags & ACPI_MADT_ENABLED))
74 return -ENODEV; 76 return -ENODEV;
75 77
76 if (device_declaration) { 78 if (device_declaration) {
@@ -87,12 +89,13 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
87 * Retrieve the ARM CPU physical identifier (MPIDR) 89 * Retrieve the ARM CPU physical identifier (MPIDR)
88 */ 90 */
89static int map_gicc_mpidr(struct acpi_subtable_header *entry, 91static int map_gicc_mpidr(struct acpi_subtable_header *entry,
90 int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr) 92 int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr,
93 bool ignore_disabled)
91{ 94{
92 struct acpi_madt_generic_interrupt *gicc = 95 struct acpi_madt_generic_interrupt *gicc =
93 container_of(entry, struct acpi_madt_generic_interrupt, header); 96 container_of(entry, struct acpi_madt_generic_interrupt, header);
94 97
95 if (!(gicc->flags & ACPI_MADT_ENABLED)) 98 if (ignore_disabled && !(gicc->flags & ACPI_MADT_ENABLED))
96 return -ENODEV; 99 return -ENODEV;
97 100
98 /* device_declaration means Device object in DSDT, in the 101 /* device_declaration means Device object in DSDT, in the
@@ -109,7 +112,7 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
109} 112}
110 113
111static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, 114static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
112 int type, u32 acpi_id) 115 int type, u32 acpi_id, bool ignore_disabled)
113{ 116{
114 unsigned long madt_end, entry; 117 unsigned long madt_end, entry;
115 phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */ 118 phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */
@@ -127,16 +130,20 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
127 struct acpi_subtable_header *header = 130 struct acpi_subtable_header *header =
128 (struct acpi_subtable_header *)entry; 131 (struct acpi_subtable_header *)entry;
129 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { 132 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
130 if (!map_lapic_id(header, acpi_id, &phys_id)) 133 if (!map_lapic_id(header, acpi_id, &phys_id,
134 ignore_disabled))
131 break; 135 break;
132 } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { 136 } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
133 if (!map_x2apic_id(header, type, acpi_id, &phys_id)) 137 if (!map_x2apic_id(header, type, acpi_id, &phys_id,
138 ignore_disabled))
134 break; 139 break;
135 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { 140 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
136 if (!map_lsapic_id(header, type, acpi_id, &phys_id)) 141 if (!map_lsapic_id(header, type, acpi_id, &phys_id,
142 ignore_disabled))
137 break; 143 break;
138 } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { 144 } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
139 if (!map_gicc_mpidr(header, type, acpi_id, &phys_id)) 145 if (!map_gicc_mpidr(header, type, acpi_id, &phys_id,
146 ignore_disabled))
140 break; 147 break;
141 } 148 }
142 entry += header->length; 149 entry += header->length;
@@ -156,14 +163,15 @@ phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
156 if (!madt) 163 if (!madt)
157 return PHYS_CPUID_INVALID; 164 return PHYS_CPUID_INVALID;
158 165
159 rv = map_madt_entry(madt, 1, acpi_id); 166 rv = map_madt_entry(madt, 1, acpi_id, true);
160 167
161 early_acpi_os_unmap_memory(madt, tbl_size); 168 early_acpi_os_unmap_memory(madt, tbl_size);
162 169
163 return rv; 170 return rv;
164} 171}
165 172
166static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id) 173static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id,
174 bool ignore_disabled)
167{ 175{
168 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 176 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
169 union acpi_object *obj; 177 union acpi_object *obj;
@@ -184,30 +192,38 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
184 192
185 header = (struct acpi_subtable_header *)obj->buffer.pointer; 193 header = (struct acpi_subtable_header *)obj->buffer.pointer;
186 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) 194 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
187 map_lapic_id(header, acpi_id, &phys_id); 195 map_lapic_id(header, acpi_id, &phys_id, ignore_disabled);
188 else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) 196 else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
189 map_lsapic_id(header, type, acpi_id, &phys_id); 197 map_lsapic_id(header, type, acpi_id, &phys_id, ignore_disabled);
190 else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) 198 else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC)
191 map_x2apic_id(header, type, acpi_id, &phys_id); 199 map_x2apic_id(header, type, acpi_id, &phys_id, ignore_disabled);
192 else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) 200 else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
193 map_gicc_mpidr(header, type, acpi_id, &phys_id); 201 map_gicc_mpidr(header, type, acpi_id, &phys_id,
202 ignore_disabled);
194 203
195exit: 204exit:
196 kfree(buffer.pointer); 205 kfree(buffer.pointer);
197 return phys_id; 206 return phys_id;
198} 207}
199 208
200phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) 209static phys_cpuid_t __acpi_get_phys_id(acpi_handle handle, int type,
210 u32 acpi_id, bool ignore_disabled)
201{ 211{
202 phys_cpuid_t phys_id; 212 phys_cpuid_t phys_id;
203 213
204 phys_id = map_mat_entry(handle, type, acpi_id); 214 phys_id = map_mat_entry(handle, type, acpi_id, ignore_disabled);
205 if (invalid_phys_cpuid(phys_id)) 215 if (invalid_phys_cpuid(phys_id))
206 phys_id = map_madt_entry(get_madt_table(), type, acpi_id); 216 phys_id = map_madt_entry(get_madt_table(), type, acpi_id,
217 ignore_disabled);
207 218
208 return phys_id; 219 return phys_id;
209} 220}
210 221
222phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
223{
224 return __acpi_get_phys_id(handle, type, acpi_id, true);
225}
226
211int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) 227int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id)
212{ 228{
213#ifdef CONFIG_SMP 229#ifdef CONFIG_SMP