diff options
author | Gu Zheng <guz.fnst@cn.fujitsu.com> | 2016-08-25 04:35:17 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-21 15:18:39 -0400 |
commit | 8ad893faf2eaedb710a3073afbb5d569df2c3e41 (patch) | |
tree | ac488564d4d25f82fbcb5e6a8f331a3eb2401b34 /drivers/acpi/processor_core.c | |
parent | 8f54969dc8d6704632b42cbb5e47730cd75cc713 (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.c | 60 |
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 | ||
34 | static int map_lapic_id(struct acpi_subtable_header *entry, | 34 | static 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 | ||
50 | static int map_x2apic_id(struct acpi_subtable_header *entry, | 50 | static 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 | ||
67 | static int map_lsapic_id(struct acpi_subtable_header *entry, | 68 | static 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 | */ |
89 | static int map_gicc_mpidr(struct acpi_subtable_header *entry, | 91 | static 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 | ||
111 | static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, | 114 | static 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 | ||
166 | static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id) | 173 | static 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 | ||
195 | exit: | 204 | exit: |
196 | kfree(buffer.pointer); | 205 | kfree(buffer.pointer); |
197 | return phys_id; | 206 | return phys_id; |
198 | } | 207 | } |
199 | 208 | ||
200 | phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) | 209 | static 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 | ||
222 | phys_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 | |||
211 | int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) | 227 | int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) |
212 | { | 228 | { |
213 | #ifdef CONFIG_SMP | 229 | #ifdef CONFIG_SMP |