1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * acpi_numa.c - ACPI NUMA support
8 #define pr_fmt(fmt) "ACPI: " fmt
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/errno.h>
15 #include <linux/acpi.h>
16 #include <linux/memblock.h>
17 #include <linux/numa.h>
18 #include <linux/nodemask.h>
19 #include <linux/topology.h>
21 static nodemask_t nodes_found_map = NODE_MASK_NONE;
23 /* maps to convert between proximity domain and logical node ID */
24 static int pxm_to_node_map[MAX_PXM_DOMAINS]
25 = { [0 ... MAX_PXM_DOMAINS - 1] = NUMA_NO_NODE };
26 static int node_to_pxm_map[MAX_NUMNODES]
27 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
29 unsigned char acpi_srat_revision __initdata;
30 int acpi_numa __initdata;
32 int pxm_to_node(int pxm)
36 return pxm_to_node_map[pxm];
38 EXPORT_SYMBOL(pxm_to_node);
40 int node_to_pxm(int node)
44 return node_to_pxm_map[node];
47 static void __acpi_map_pxm_to_node(int pxm, int node)
49 if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
50 pxm_to_node_map[pxm] = node;
51 if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
52 node_to_pxm_map[node] = pxm;
55 int acpi_map_pxm_to_node(int pxm)
59 if (pxm < 0 || pxm >= MAX_PXM_DOMAINS || numa_off)
62 node = pxm_to_node_map[pxm];
64 if (node == NUMA_NO_NODE) {
65 if (nodes_weight(nodes_found_map) >= MAX_NUMNODES)
67 node = first_unset_node(nodes_found_map);
68 __acpi_map_pxm_to_node(pxm, node);
69 node_set(node, nodes_found_map);
74 EXPORT_SYMBOL(acpi_map_pxm_to_node);
77 acpi_table_print_srat_entry(struct acpi_subtable_header *header)
79 switch (header->type) {
80 case ACPI_SRAT_TYPE_CPU_AFFINITY:
82 struct acpi_srat_cpu_affinity *p =
83 (struct acpi_srat_cpu_affinity *)header;
84 pr_debug("SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
85 p->apic_id, p->local_sapic_eid,
86 p->proximity_domain_lo,
87 (p->flags & ACPI_SRAT_CPU_ENABLED) ?
88 "enabled" : "disabled");
92 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
94 struct acpi_srat_mem_affinity *p =
95 (struct acpi_srat_mem_affinity *)header;
96 pr_debug("SRAT Memory (0x%llx length 0x%llx) in proximity domain %d %s%s%s\n",
97 (unsigned long long)p->base_address,
98 (unsigned long long)p->length,
100 (p->flags & ACPI_SRAT_MEM_ENABLED) ?
101 "enabled" : "disabled",
102 (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
103 " hot-pluggable" : "",
104 (p->flags & ACPI_SRAT_MEM_NON_VOLATILE) ?
105 " non-volatile" : "");
109 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
111 struct acpi_srat_x2apic_cpu_affinity *p =
112 (struct acpi_srat_x2apic_cpu_affinity *)header;
113 pr_debug("SRAT Processor (x2apicid[0x%08x]) in proximity domain %d %s\n",
116 (p->flags & ACPI_SRAT_CPU_ENABLED) ?
117 "enabled" : "disabled");
121 case ACPI_SRAT_TYPE_GICC_AFFINITY:
123 struct acpi_srat_gicc_affinity *p =
124 (struct acpi_srat_gicc_affinity *)header;
125 pr_debug("SRAT Processor (acpi id[0x%04x]) in proximity domain %d %s\n",
126 p->acpi_processor_uid,
128 (p->flags & ACPI_SRAT_GICC_ENABLED) ?
129 "enabled" : "disabled");
134 pr_warn("Found unsupported SRAT entry (type = 0x%x)\n",
141 * A lot of BIOS fill in 10 (= no distance) everywhere. This messes
142 * up the NUMA heuristics which wants the local node to have a smaller
143 * distance than the others.
144 * Do some quick checks here and only use the SLIT if it passes.
146 static int __init slit_valid(struct acpi_table_slit *slit)
149 int d = slit->locality_count;
150 for (i = 0; i < d; i++) {
151 for (j = 0; j < d; j++) {
152 u8 val = slit->entry[d*i + j];
154 if (val != LOCAL_DISTANCE)
156 } else if (val <= LOCAL_DISTANCE)
163 void __init bad_srat(void)
165 pr_err("SRAT: SRAT not used.\n");
169 int __init srat_disabled(void)
171 return acpi_numa < 0;
174 #if defined(CONFIG_X86) || defined(CONFIG_ARM64)
176 * Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
177 * I/O localities since SRAT does not list them. I/O localities are
178 * not supported at this point.
180 void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
184 for (i = 0; i < slit->locality_count; i++) {
185 const int from_node = pxm_to_node(i);
187 if (from_node == NUMA_NO_NODE)
190 for (j = 0; j < slit->locality_count; j++) {
191 const int to_node = pxm_to_node(j);
193 if (to_node == NUMA_NO_NODE)
196 numa_set_distance(from_node, to_node,
197 slit->entry[slit->locality_count * i + j]);
203 * Default callback for parsing of the Proximity Domain <-> Memory
207 acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
215 if (ma->header.length < sizeof(struct acpi_srat_mem_affinity)) {
216 pr_err("SRAT: Unexpected header length: %d\n",
218 goto out_err_bad_srat;
220 if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
222 hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE;
223 if (hotpluggable && !IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
226 start = ma->base_address;
227 end = start + ma->length;
228 pxm = ma->proximity_domain;
229 if (acpi_srat_revision <= 1)
232 node = acpi_map_pxm_to_node(pxm);
233 if (node == NUMA_NO_NODE) {
234 pr_err("SRAT: Too many proximity domains.\n");
235 goto out_err_bad_srat;
238 if (numa_add_memblk(node, start, end) < 0) {
239 pr_err("SRAT: Failed to add memblk to node %u [mem %#010Lx-%#010Lx]\n",
240 node, (unsigned long long) start,
241 (unsigned long long) end - 1);
242 goto out_err_bad_srat;
245 node_set(node, numa_nodes_parsed);
247 pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s%s\n",
249 (unsigned long long) start, (unsigned long long) end - 1,
250 hotpluggable ? " hotplug" : "",
251 ma->flags & ACPI_SRAT_MEM_NON_VOLATILE ? " non-volatile" : "");
253 /* Mark hotplug range in memblock. */
254 if (hotpluggable && memblock_mark_hotplug(start, ma->length))
255 pr_warn("SRAT: Failed to mark hotplug range [mem %#010Lx-%#010Lx] in memblock\n",
256 (unsigned long long)start, (unsigned long long)end - 1);
258 max_possible_pfn = max(max_possible_pfn, PFN_UP(end - 1));
266 #endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
268 static int __init acpi_parse_slit(struct acpi_table_header *table)
270 struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
272 if (!slit_valid(slit)) {
273 pr_info("SLIT table looks invalid. Not used.\n");
276 acpi_numa_slit_init(slit);
282 acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
284 pr_warn("Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
288 acpi_parse_x2apic_affinity(union acpi_subtable_headers *header,
289 const unsigned long end)
291 struct acpi_srat_x2apic_cpu_affinity *processor_affinity;
293 processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
295 acpi_table_print_srat_entry(&header->common);
297 /* let architecture-dependent part to do it */
298 acpi_numa_x2apic_affinity_init(processor_affinity);
304 acpi_parse_processor_affinity(union acpi_subtable_headers *header,
305 const unsigned long end)
307 struct acpi_srat_cpu_affinity *processor_affinity;
309 processor_affinity = (struct acpi_srat_cpu_affinity *)header;
311 acpi_table_print_srat_entry(&header->common);
313 /* let architecture-dependent part to do it */
314 acpi_numa_processor_affinity_init(processor_affinity);
320 acpi_parse_gicc_affinity(union acpi_subtable_headers *header,
321 const unsigned long end)
323 struct acpi_srat_gicc_affinity *processor_affinity;
325 processor_affinity = (struct acpi_srat_gicc_affinity *)header;
327 acpi_table_print_srat_entry(&header->common);
329 /* let architecture-dependent part to do it */
330 acpi_numa_gicc_affinity_init(processor_affinity);
335 static int __initdata parsed_numa_memblks;
338 acpi_parse_memory_affinity(union acpi_subtable_headers * header,
339 const unsigned long end)
341 struct acpi_srat_mem_affinity *memory_affinity;
343 memory_affinity = (struct acpi_srat_mem_affinity *)header;
345 acpi_table_print_srat_entry(&header->common);
347 /* let architecture-dependent part to do it */
348 if (!acpi_numa_memory_affinity_init(memory_affinity))
349 parsed_numa_memblks++;
353 static int __init acpi_parse_srat(struct acpi_table_header *table)
355 struct acpi_table_srat *srat = (struct acpi_table_srat *)table;
357 acpi_srat_revision = srat->header.revision;
359 /* Real work done in acpi_table_parse_srat below. */
365 acpi_table_parse_srat(enum acpi_srat_type id,
366 acpi_tbl_entry_handler handler, unsigned int max_entries)
368 return acpi_table_parse_entries(ACPI_SIG_SRAT,
369 sizeof(struct acpi_table_srat), id,
370 handler, max_entries);
373 int __init acpi_numa_init(void)
381 * Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
382 * SRAT cpu entries could have different order with that in MADT.
383 * So go over all cpu entries in SRAT to get apicid to node mapping.
386 /* SRAT: System Resource Affinity Table */
387 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
388 struct acpi_subtable_proc srat_proc[3];
390 memset(srat_proc, 0, sizeof(srat_proc));
391 srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY;
392 srat_proc[0].handler = acpi_parse_processor_affinity;
393 srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY;
394 srat_proc[1].handler = acpi_parse_x2apic_affinity;
395 srat_proc[2].id = ACPI_SRAT_TYPE_GICC_AFFINITY;
396 srat_proc[2].handler = acpi_parse_gicc_affinity;
398 acpi_table_parse_entries_array(ACPI_SIG_SRAT,
399 sizeof(struct acpi_table_srat),
400 srat_proc, ARRAY_SIZE(srat_proc), 0);
402 cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
403 acpi_parse_memory_affinity, 0);
406 /* SLIT: System Locality Information Table */
407 acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
411 else if (!parsed_numa_memblks)
416 static int acpi_get_pxm(acpi_handle h)
418 unsigned long long pxm;
421 acpi_handle phandle = h;
425 status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
426 if (ACPI_SUCCESS(status))
428 status = acpi_get_parent(handle, &phandle);
429 } while (ACPI_SUCCESS(status));
433 int acpi_get_node(acpi_handle handle)
437 pxm = acpi_get_pxm(handle);
439 return acpi_map_pxm_to_node(pxm);
441 EXPORT_SYMBOL(acpi_get_node);