Skip to content

Commit fd49f99

Browse files
AlisonSchofielddjbw
authored andcommitted
ACPI: NUMA: Add a node and memblk for each CFMWS not in SRAT
During NUMA init, CXL memory defined in the SRAT Memory Affinity subtable may be assigned to a NUMA node. Since there is no requirement that the SRAT be comprehensive for CXL memory another mechanism is needed to assign NUMA nodes to CXL memory not identified in the SRAT. Use the CXL Fixed Memory Window Structure (CFMWS) of the ACPI CXL Early Discovery Table (CEDT) to find all CXL memory ranges. Create a NUMA node for each CFMWS that is not already assigned to a NUMA node. Add a memblk attaching its host physical address range to the node. Note that these ranges may not actually map any memory at boot time. They may describe persistent capacity or may be present to enable hot-plug. Consumers can use phys_to_target_node() to discover the NUMA node. Signed-off-by: Alison Schofield <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Link: https://lore.kernel.org/r/163553711933.2509508.2203471175679990.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams <[email protected]>
1 parent 814dff9 commit fd49f99

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

drivers/acpi/numa/srat.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,47 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
298298
out_err:
299299
return -EINVAL;
300300
}
301+
302+
static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
303+
void *arg, const unsigned long table_end)
304+
{
305+
struct acpi_cedt_cfmws *cfmws;
306+
int *fake_pxm = arg;
307+
u64 start, end;
308+
int node;
309+
310+
cfmws = (struct acpi_cedt_cfmws *)header;
311+
start = cfmws->base_hpa;
312+
end = cfmws->base_hpa + cfmws->window_size;
313+
314+
/* Skip if the SRAT already described the NUMA details for this HPA */
315+
node = phys_to_target_node(start);
316+
if (node != NUMA_NO_NODE)
317+
return 0;
318+
319+
node = acpi_map_pxm_to_node(*fake_pxm);
320+
321+
if (node == NUMA_NO_NODE) {
322+
pr_err("ACPI NUMA: Too many proximity domains while processing CFMWS.\n");
323+
return -EINVAL;
324+
}
325+
326+
if (numa_add_memblk(node, start, end) < 0) {
327+
/* CXL driver must handle the NUMA_NO_NODE case */
328+
pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n",
329+
node, start, end);
330+
}
331+
332+
/* Set the next available fake_pxm value */
333+
(*fake_pxm)++;
334+
return 0;
335+
}
336+
#else
337+
static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
338+
void *arg, const unsigned long table_end)
339+
{
340+
return 0;
341+
}
301342
#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
302343

303344
static int __init acpi_parse_slit(struct acpi_table_header *table)
@@ -442,7 +483,7 @@ acpi_table_parse_srat(enum acpi_srat_type id,
442483

443484
int __init acpi_numa_init(void)
444485
{
445-
int cnt = 0;
486+
int i, fake_pxm, cnt = 0;
446487

447488
if (acpi_disabled)
448489
return -EINVAL;
@@ -478,6 +519,22 @@ int __init acpi_numa_init(void)
478519
/* SLIT: System Locality Information Table */
479520
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
480521

522+
/*
523+
* CXL Fixed Memory Window Structures (CFMWS) must be parsed
524+
* after the SRAT. Create NUMA Nodes for CXL memory ranges that
525+
* are defined in the CFMWS and not already defined in the SRAT.
526+
* Initialize a fake_pxm as the first available PXM to emulate.
527+
*/
528+
529+
/* fake_pxm is the next unused PXM value after SRAT parsing */
530+
for (i = 0, fake_pxm = -1; i < MAX_NUMNODES - 1; i++) {
531+
if (node_to_pxm_map[i] > fake_pxm)
532+
fake_pxm = node_to_pxm_map[i];
533+
}
534+
fake_pxm++;
535+
acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, acpi_parse_cfmws,
536+
&fake_pxm);
537+
481538
if (cnt < 0)
482539
return cnt;
483540
else if (!parsed_numa_memblks)

drivers/cxl/acpi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
125125
cfmws->base_hpa + cfmws->window_size - 1);
126126
return 0;
127127
}
128-
dev_dbg(dev, "add: %s range %#llx-%#llx\n", dev_name(&cxld->dev),
128+
dev_dbg(dev, "add: %s node: %d range %#llx-%#llx\n",
129+
dev_name(&cxld->dev), phys_to_target_node(cxld->range.start),
129130
cfmws->base_hpa, cfmws->base_hpa + cfmws->window_size - 1);
130131

131132
return 0;

0 commit comments

Comments
 (0)