Some fixes and updates for SRAT/CEDT parsing code. Patches can be
applied individually and are independent.
First patch fixes a page fault during boot (fix as suggested by Dan).
Patches 2 to 4 remove architectural code no longer needed.
Patches 5 to 7 add diagnostic printouts for CEDT.
Changelog:
v5:
* dropped: "x86/numa: Fix SRAT lookup of CFMWS ranges with
numa_fill_memblks()"
* added: "ACPI/NUMA: Return memblk modification state from
numa_fill_memblks()"
* conditionally print CEDT extended memblks
v4:
* updated SOB chains and desription
* added patch "x86/numa: Remove numa_fill_memblks() from sparsemem.h
using __weak"
* Reordered patches to move CEDT table printout as an option at the
end
* split print table patch and added: "ACPI/NUMA: Add log messages for
memory ranges found in CEDT"
v3:
* Rebased onto v6.9-rc1
* Fixing x86 build error in sparsemem.h [Dan/Alison]
* Added CEDT node info [Alison]
* Use pr_debug() for table output [Dan]
* Refactoring split in 3 patches [Dan]
* Fixed performance regression introduced [kbot]
* Fixed checkpatch issues [Dan]
Robert Richter (7):
x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks()
ACPI/NUMA: Remove architecture dependent remainings
ACPI/NUMA: Squash acpi_numa_slit_init() into acpi_parse_slit()
ACPI/NUMA: Squash acpi_numa_memory_affinity_init() into
acpi_parse_memory_affinity()
ACPI/NUMA: Return memblk modification state from numa_fill_memblks()
ACPI/NUMA: Add log messages for memory ranges found in CEDT
ACPI/NUMA: Print CXL Early Discovery Table (CEDT)
arch/x86/include/asm/numa.h | 1 +
arch/x86/include/asm/sparsemem.h | 2 -
arch/x86/mm/numa.c | 37 +++---
drivers/acpi/numa/srat.c | 207 +++++++++++++++++++++++--------
include/linux/acpi.h | 5 -
include/linux/numa.h | 7 --
6 files changed, 176 insertions(+), 83 deletions(-)
base-commit: 62dba604a4883169abf959b7d09449900e7d4537
--
2.39.2
For configurations that have the kconfig option NUMA_KEEP_MEMINFO
disabled numa_fill_memblks() only returns with NUMA_NO_MEMBLK (-1).
SRAT lookup fails then because an existing SRAT memory range cannot be
found for a CFMWS address range. This causes the addition of a
duplicate numa_memblk with a different node id and a subsequent page
fault and kernel crash during boot.
Fix this by making numa_fill_memblks() always available regardless of
NUMA_KEEP_MEMINFO.
The fix also removes numa_fill_memblks() from sparsemem.h using
__weak.
From Dan:
"""
It just feels like numa_fill_memblks() has absolutely no business being
defined in arch/x86/include/asm/sparsemem.h.
The only use for numa_fill_memblks() is to arrange for NUMA nodes to be
applied to memory ranges hot-onlined by the CXL driver.
It belongs right next to numa_add_memblk(), and I suspect
arch/x86/include/asm/sparsemem.h was only chosen to avoid figuring out
what to do about the fact that linux/numa.h does not include asm/numa.h
and that all implementations either provide numa_add_memblk() or select
the generic implementation.
So I would prefer that this do the proper fix and get
numa_fill_memblks() completely out of the sparsemem.h path.
Something like the following which boots for me.
"""
Note that the issue was initially introduced with [1]. But since
phys_to_target_node() was originally used that returned the valid node
0, an additional numa_memblk was not added. Though, the node id was
wrong too, a message is seen then in the logs:
kernel/numa.c: pr_info_once("Unknown target node for memory at 0x%llx, assuming node 0\n",
[1] commit fd49f99c1809 ("ACPI: NUMA: Add a node and memblk for each
CFMWS not in SRAT")
Suggested-by: Dan Williams <[email protected]>
Link: https://lore.kernel.org/all/[email protected]/
Fixes: 8f1004679987 ("ACPI/NUMA: Apply SRAT proximity domain to entire CFMWS window")
Cc: Derick Marks <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Alison Schofield <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
---
Authorship can be changed to Dan's if he wants to but that needs his
Signed-off-by.
---
arch/x86/include/asm/numa.h | 1 +
arch/x86/include/asm/sparsemem.h | 2 --
arch/x86/mm/numa.c | 4 ++--
drivers/acpi/numa/srat.c | 5 +++++
include/linux/numa.h | 7 -------
5 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h
index ef2844d69173..12a93a3466c4 100644
--- a/arch/x86/include/asm/numa.h
+++ b/arch/x86/include/asm/numa.h
@@ -26,6 +26,7 @@ extern s16 __apicid_to_node[MAX_LOCAL_APIC];
extern nodemask_t numa_nodes_parsed __initdata;
extern int __init numa_add_memblk(int nodeid, u64 start, u64 end);
+extern int __init numa_fill_memblks(u64 start, u64 end);
extern void __init numa_set_distance(int from, int to, int distance);
static inline void set_apicid_to_node(int apicid, s16 node)
diff --git a/arch/x86/include/asm/sparsemem.h b/arch/x86/include/asm/sparsemem.h
index 1be13b2dfe8b..64df897c0ee3 100644
--- a/arch/x86/include/asm/sparsemem.h
+++ b/arch/x86/include/asm/sparsemem.h
@@ -37,8 +37,6 @@ extern int phys_to_target_node(phys_addr_t start);
#define phys_to_target_node phys_to_target_node
extern int memory_add_physaddr_to_nid(u64 start);
#define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
-extern int numa_fill_memblks(u64 start, u64 end);
-#define numa_fill_memblks numa_fill_memblks
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 65e9a6e391c0..ce84ba86e69e 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -929,6 +929,8 @@ int memory_add_physaddr_to_nid(u64 start)
}
EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
+
static int __init cmp_memblk(const void *a, const void *b)
{
const struct numa_memblk *ma = *(const struct numa_memblk **)a;
@@ -1001,5 +1003,3 @@ int __init numa_fill_memblks(u64 start, u64 end)
}
return 0;
}
-
-#endif
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index e45e64993c50..3b09fd39eeb4 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -208,6 +208,11 @@ int __init srat_disabled(void)
return acpi_numa < 0;
}
+__weak int __init numa_fill_memblks(u64 start, u64 end)
+{
+ return NUMA_NO_MEMBLK;
+}
+
#if defined(CONFIG_X86) || defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
/*
* Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
diff --git a/include/linux/numa.h b/include/linux/numa.h
index 915033a75731..8485d98e554d 100644
--- a/include/linux/numa.h
+++ b/include/linux/numa.h
@@ -36,13 +36,6 @@ int memory_add_physaddr_to_nid(u64 start);
int phys_to_target_node(u64 start);
#endif
-#ifndef numa_fill_memblks
-static inline int __init numa_fill_memblks(u64 start, u64 end)
-{
- return NUMA_NO_MEMBLK;
-}
-#endif
-
#else /* !CONFIG_NUMA */
static inline int numa_nearest_node(int node, unsigned int state)
{
--
2.39.2
With the removal of the Itanium architecture [1] the last architecture
dependent functions:
acpi_numa_slit_init(), acpi_numa_memory_affinity_init()
were removed. Remove its remainings in the header files too and make
them static.
[1] commit cf8e8658100d ("arch: Remove Itanium (IA-64) architecture")
Reviewed-by: Dan Williams <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
---
drivers/acpi/numa/srat.c | 16 ++--------------
include/linux/acpi.h | 5 -----
2 files changed, 2 insertions(+), 19 deletions(-)
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 3b09fd39eeb4..e4d53e3660fd 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -213,13 +213,12 @@ __weak int __init numa_fill_memblks(u64 start, u64 end)
return NUMA_NO_MEMBLK;
}
-#if defined(CONFIG_X86) || defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
/*
* Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
* I/O localities since SRAT does not list them. I/O localities are
* not supported at this point.
*/
-void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
+static void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
{
int i, j;
@@ -241,11 +240,7 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
}
}
-/*
- * Default callback for parsing of the Proximity Domain <-> Memory
- * Area mappings
- */
-int __init
+static int __init
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
{
u64 start, end;
@@ -345,13 +340,6 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
(*fake_pxm)++;
return 0;
}
-#else
-static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
- void *arg, const unsigned long table_end)
-{
- return 0;
-}
-#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
static int __init acpi_parse_slit(struct acpi_table_header *table)
{
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 34829f2c517a..2c227b61a452 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -242,9 +242,6 @@ static inline bool acpi_gicc_is_usable(struct acpi_madt_generic_interrupt *gicc)
return gicc->flags & ACPI_MADT_ENABLED;
}
-/* the following numa functions are architecture-dependent */
-void acpi_numa_slit_init (struct acpi_table_slit *slit);
-
#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
#else
@@ -267,8 +264,6 @@ static inline void
acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
#endif
-int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
-
#ifndef PHYS_CPUID_INVALID
typedef u32 phys_cpuid_t;
#define PHYS_CPUID_INVALID (phys_cpuid_t)(-1)
--
2.39.2
Adding a pr_info() when successfully adding a CFMWS memory range.
Suggested-by: Alison Schofield <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
---
drivers/acpi/numa/srat.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 76b39a6d3aef..34ecf2dc912f 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -339,8 +339,12 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
* window.
*/
modified = numa_fill_memblks(start, end);
- if (modified != NUMA_NO_MEMBLK)
+ if (modified != NUMA_NO_MEMBLK) {
+ if (modified)
+ pr_info("CEDT: memblk extended [mem %#010Lx-%#010Lx]\n",
+ (unsigned long long) start, (unsigned long long) end - 1);
return 0;
+ }
/* No SRAT description. Create a new node. */
node = acpi_map_pxm_to_node(*fake_pxm);
@@ -355,8 +359,13 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n",
node, start, end);
}
+
node_set(node, numa_nodes_parsed);
+ pr_info("CEDT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
+ node, *fake_pxm,
+ (unsigned long long) start, (unsigned long long) end - 1);
+
/* Set the next available fake_pxm value */
(*fake_pxm)++;
return 0;
--
2.39.2
After removing architectural code the helper function
acpi_numa_slit_init() is no longer needed. Squash it into
acpi_parse_slit(). No functional changes intended.
Reviewed-by: Dan Williams <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
---
drivers/acpi/numa/srat.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index e4d53e3660fd..430ddcfb8312 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -218,10 +218,16 @@ __weak int __init numa_fill_memblks(u64 start, u64 end)
* I/O localities since SRAT does not list them. I/O localities are
* not supported at this point.
*/
-static void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
+static int __init acpi_parse_slit(struct acpi_table_header *table)
{
+ struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
int i, j;
+ if (!slit_valid(slit)) {
+ pr_info("SLIT table looks invalid. Not used.\n");
+ return -EINVAL;
+ }
+
for (i = 0; i < slit->locality_count; i++) {
const int from_node = pxm_to_node(i);
@@ -238,6 +244,8 @@ static void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
slit->entry[slit->locality_count * i + j]);
}
}
+
+ return 0;
}
static int __init
@@ -341,19 +349,6 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
return 0;
}
-static int __init acpi_parse_slit(struct acpi_table_header *table)
-{
- struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
-
- if (!slit_valid(slit)) {
- pr_info("SLIT table looks invalid. Not used.\n");
- return -EINVAL;
- }
- acpi_numa_slit_init(slit);
-
- return 0;
-}
-
void __init __weak
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
{
--
2.39.2
When registering a memory range a possibly overlapping memory block
will be extended instead of creating a new one. If both ranges exactly
overlap, the blocks remain unchanged and are just reused. The
information if a memblock was extended is useful for diagnostics.
Change return code of numa_fill_memblks() to also report if memblocks
have been modified.
Link: https://lore.kernel.org/all/ZiqnbD0CB9WUL1zu@aschofie-mobl2/T/#u
Cc: Alison Schofield <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
---
arch/x86/mm/numa.c | 33 ++++++++++++++++++---------------
drivers/acpi/numa/srat.c | 5 +++--
2 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index ce84ba86e69e..e34e96d57656 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -950,15 +950,16 @@ static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata;
* address range @start-@end
*
* RETURNS:
- * 0 : Success
- * NUMA_NO_MEMBLK : No memblks exist in address range @start-@end
+ * NUMA_NO_MEMBLK if no memblks exist in address range @start-@end,
+ * zero on success without blocks modified and non-zero positive
+ * values on success with blocks modified.
*/
int __init numa_fill_memblks(u64 start, u64 end)
{
struct numa_memblk **blk = &numa_memblk_list[0];
struct numa_meminfo *mi = &numa_meminfo;
- int count = 0;
+ int count = 0, modified = 0;
u64 prev_end;
/*
@@ -981,25 +982,27 @@ int __init numa_fill_memblks(u64 start, u64 end)
/* Sort the list of pointers in memblk->start order */
sort(&blk[0], count, sizeof(blk[0]), cmp_memblk, NULL);
- /* Make sure the first/last memblks include start/end */
- blk[0]->start = min(blk[0]->start, start);
- blk[count - 1]->end = max(blk[count - 1]->end, end);
-
/*
* Fill any gaps by tracking the previous memblks
* end address and backfilling to it if needed.
*/
- prev_end = blk[0]->end;
- for (int i = 1; i < count; i++) {
+ prev_end = start;
+ for (int i = 0; i < count; i++) {
struct numa_memblk *curr = blk[i];
- if (prev_end >= curr->start) {
- if (prev_end < curr->end)
- prev_end = curr->end;
- } else {
+ if (prev_end < curr->start) {
curr->start = prev_end;
- prev_end = curr->end;
+ modified = 1;
}
+
+ if (prev_end < curr->end)
+ prev_end = curr->end;
}
- return 0;
+
+ if (blk[count - 1]->end < end) {
+ blk[count - 1]->end = end;
+ modified = 1;
+ }
+
+ return modified;
}
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index e3f26e71637a..76b39a6d3aef 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -326,7 +326,7 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
struct acpi_cedt_cfmws *cfmws;
int *fake_pxm = arg;
u64 start, end;
- int node;
+ int node, modified;
cfmws = (struct acpi_cedt_cfmws *)header;
start = cfmws->base_hpa;
@@ -338,7 +338,8 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
* found for any portion of the window to cover the entire
* window.
*/
- if (!numa_fill_memblks(start, end))
+ modified = numa_fill_memblks(start, end);
+ if (modified != NUMA_NO_MEMBLK)
return 0;
/* No SRAT description. Create a new node. */
--
2.39.2
After removing architectural code the helper function
acpi_numa_memory_affinity_init() is no longer needed. Squash it into
acpi_parse_memory_affinity(). No functional changes intended.
While at it, fixing checkpatch complaints in code moved.
Reported-by: kernel test robot <[email protected]>
Closes: https://lore.kernel.org/oe-lkp/[email protected]
Reviewed-by: Dan Williams <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
---
drivers/acpi/numa/srat.c | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 430ddcfb8312..e3f26e71637a 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -248,22 +248,30 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
return 0;
}
+static int parsed_numa_memblks __initdata;
+
static int __init
-acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
+acpi_parse_memory_affinity(union acpi_subtable_headers *header,
+ const unsigned long table_end)
{
+ struct acpi_srat_mem_affinity *ma;
u64 start, end;
u32 hotpluggable;
int node, pxm;
+ ma = (struct acpi_srat_mem_affinity *)header;
+
+ acpi_table_print_srat_entry(&header->common);
+
if (srat_disabled())
- goto out_err;
+ return 0;
if (ma->header.length < sizeof(struct acpi_srat_mem_affinity)) {
pr_err("SRAT: Unexpected header length: %d\n",
ma->header.length);
goto out_err_bad_srat;
}
if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
- goto out_err;
+ return 0;
hotpluggable = IS_ENABLED(CONFIG_MEMORY_HOTPLUG) &&
(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE);
@@ -301,11 +309,15 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
max_possible_pfn = max(max_possible_pfn, PFN_UP(end - 1));
+ parsed_numa_memblks++;
+
return 0;
+
out_err_bad_srat:
+ /* Just disable SRAT, but do not fail and ignore errors. */
bad_srat();
-out_err:
- return -EINVAL;
+
+ return 0;
}
static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
@@ -438,24 +450,6 @@ acpi_parse_gi_affinity(union acpi_subtable_headers *header,
}
#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
-static int __initdata parsed_numa_memblks;
-
-static int __init
-acpi_parse_memory_affinity(union acpi_subtable_headers * header,
- const unsigned long end)
-{
- struct acpi_srat_mem_affinity *memory_affinity;
-
- memory_affinity = (struct acpi_srat_mem_affinity *)header;
-
- acpi_table_print_srat_entry(&header->common);
-
- /* let architecture-dependent part to do it */
- if (!acpi_numa_memory_affinity_init(memory_affinity))
- parsed_numa_memblks++;
- return 0;
-}
-
static int __init acpi_parse_srat(struct acpi_table_header *table)
{
struct acpi_table_srat *srat = (struct acpi_table_srat *)table;
--
2.39.2
The CEDT contains similar entries as the SRAT. For diagnostic reasons
print the CEDT same style as the SRAT.
Signed-off-by: Robert Richter <[email protected]>
---
drivers/acpi/numa/srat.c | 111 +++++++++++++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 34ecf2dc912f..fa21d4d5fccf 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -320,6 +320,114 @@ acpi_parse_memory_affinity(union acpi_subtable_headers *header,
return 0;
}
+static int __init
+__acpi_table_print_cedt_entry(union acpi_subtable_headers *__header,
+ void *arg, const unsigned long table_end)
+{
+ struct acpi_cedt_header *header = (struct acpi_cedt_header *)__header;
+
+ switch (header->type) {
+ case ACPI_CEDT_TYPE_CHBS:
+ {
+ struct acpi_cedt_chbs *p =
+ (struct acpi_cedt_chbs *)header;
+
+ if (header->length < sizeof(struct acpi_cedt_chbs)) {
+ pr_warn("CEDT: unsupported CHBS entry: size %d\n",
+ header->length);
+ break;
+ }
+
+ pr_debug("CEDT: CHBS (0x%llx length 0x%llx uid %lu) %s (%d)\n",
+ (unsigned long long)p->base,
+ (unsigned long long)p->length,
+ (unsigned long)p->uid,
+ (p->cxl_version == ACPI_CEDT_CHBS_VERSION_CXL11) ?
+ "cxl11" :
+ (p->cxl_version == ACPI_CEDT_CHBS_VERSION_CXL20) ?
+ "cxl20" :
+ "unsupported version",
+ p->cxl_version);
+ }
+ break;
+ case ACPI_CEDT_TYPE_CFMWS:
+ {
+ struct acpi_cedt_cfmws *p =
+ (struct acpi_cedt_cfmws *)header;
+ int eiw_to_ways[] = {1, 2, 4, 8, 16, 3, 6, 12};
+ int targets = -1;
+
+ if (header->length < sizeof(struct acpi_cedt_cfmws)) {
+ pr_warn("CEDT: unsupported CFMWS entry: size %d\n",
+ header->length);
+ break;
+ }
+
+ if (p->interleave_ways < ARRAY_SIZE(eiw_to_ways))
+ targets = eiw_to_ways[p->interleave_ways];
+ if (header->length < struct_size(
+ p, interleave_targets, targets))
+ targets = -1;
+
+ pr_debug("CEDT: CFMWS (0x%llx length 0x%llx) with %d target%s",
+ (unsigned long long)p->base_hpa,
+ (unsigned long long)p->window_size,
+ targets, targets > 1 ? "s" : "");
+ for (int i = 0; i < targets; i++)
+ pr_cont("%s%lu", i ? ", " : " (",
+ (unsigned long)p->interleave_targets[i]);
+ pr_cont("%s%s%s%s%s%s\n",
+ targets > 0 ? ")" : "",
+ (p->restrictions & ACPI_CEDT_CFMWS_RESTRICT_TYPE2) ?
+ " type2" : "",
+ (p->restrictions & ACPI_CEDT_CFMWS_RESTRICT_TYPE3) ?
+ " type3" : "",
+ (p->restrictions & ACPI_CEDT_CFMWS_RESTRICT_VOLATILE) ?
+ " volatile" : "",
+ (p->restrictions & ACPI_CEDT_CFMWS_RESTRICT_PMEM) ?
+ " pmem" : "",
+ (p->restrictions & ACPI_CEDT_CFMWS_RESTRICT_FIXED) ?
+ " fixed" : "");
+ }
+ break;
+ case ACPI_CEDT_TYPE_CXIMS:
+ {
+ struct acpi_cedt_cxims *p =
+ (struct acpi_cedt_cxims *)header;
+
+ if (header->length < sizeof(struct acpi_cedt_cxims)) {
+ pr_warn("CEDT: unsupported CXIMS entry: size %d\n",
+ header->length);
+ break;
+ }
+
+ pr_debug("CEDT: CXIMS (hbig %u nr_xormaps %u)\n",
+ (unsigned int)p->hbig,
+ (unsigned int)p->nr_xormaps);
+ }
+ break;
+ default:
+ pr_warn("CEDT: Found unsupported entry (type = 0x%x)\n",
+ header->type);
+ break;
+ }
+
+ return 0;
+}
+
+static void __init acpi_table_print_cedt_entry(enum acpi_cedt_type id)
+{
+ acpi_table_parse_cedt(id, __acpi_table_print_cedt_entry, NULL);
+}
+
+static void __init acpi_table_print_cedt(void)
+{
+ /* Print only implemented CEDT types */
+ acpi_table_print_cedt_entry(ACPI_CEDT_TYPE_CHBS);
+ acpi_table_print_cedt_entry(ACPI_CEDT_TYPE_CFMWS);
+ acpi_table_print_cedt_entry(ACPI_CEDT_TYPE_CXIMS);
+}
+
static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
void *arg, const unsigned long table_end)
{
@@ -518,6 +626,9 @@ int __init acpi_numa_init(void)
/* SLIT: System Locality Information Table */
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
+ /* CEDT: CXL Early Discovery Table */
+ acpi_table_print_cedt();
+
/*
* CXL Fixed Memory Window Structures (CFMWS) must be parsed
* after the SRAT. Create NUMA Nodes for CXL memory ranges that
--
2.39.2
Hi Robert,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 62dba604a4883169abf959b7d09449900e7d4537]
url: https://github.com/intel-lab-lkp/linux/commits/Robert-Richter/x86-numa-Fix-SRAT-lookup-of-CFMWS-ranges-with-numa_fill_memblks/20240429-205337
base: 62dba604a4883169abf959b7d09449900e7d4537
patch link: https://lore.kernel.org/r/20240429124955.2294014-2-rrichter%40amd.com
patch subject: [PATCH v5 1/7] x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks()
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20240430/[email protected]/config)
compiler: loongarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240430/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
>> drivers/acpi/numa/srat.c:211:19: warning: no previous prototype for 'numa_fill_memblks' [-Wmissing-prototypes]
211 | __weak int __init numa_fill_memblks(u64 start, u64 end)
| ^~~~~~~~~~~~~~~~~
vim +/numa_fill_memblks +211 drivers/acpi/numa/srat.c
210
> 211 __weak int __init numa_fill_memblks(u64 start, u64 end)
212 {
213 return NUMA_NO_MEMBLK;
214 }
215
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Robert,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 62dba604a4883169abf959b7d09449900e7d4537]
url: https://github.com/intel-lab-lkp/linux/commits/Robert-Richter/x86-numa-Fix-SRAT-lookup-of-CFMWS-ranges-with-numa_fill_memblks/20240429-205337
base: 62dba604a4883169abf959b7d09449900e7d4537
patch link: https://lore.kernel.org/r/20240429124955.2294014-2-rrichter%40amd.com
patch subject: [PATCH v5 1/7] x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks()
config: arm64-randconfig-r121-20240430 (https://download.01.org/0day-ci/archive/20240430/[email protected]/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 37ae4ad0eef338776c7e2cffb3896153d43dcd90)
reproduce: (https://download.01.org/0day-ci/archive/20240430/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
In file included from drivers/acpi/numa/srat.c:15:
In file included from include/linux/acpi.h:39:
In file included from include/acpi/acpi_io.h:7:
In file included from arch/arm64/include/asm/acpi.h:14:
In file included from include/linux/memblock.h:12:
In file included from include/linux/mm.h:2208:
include/linux/vmstat.h:508:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
508 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
509 | item];
| ~~~~
include/linux/vmstat.h:515:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
515 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
516 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
522 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
include/linux/vmstat.h:527:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
527 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
528 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmstat.h:536:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
536 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
537 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/acpi/numa/srat.c:211:19: warning: no previous prototype for function 'numa_fill_memblks' [-Wmissing-prototypes]
211 | __weak int __init numa_fill_memblks(u64 start, u64 end)
| ^
drivers/acpi/numa/srat.c:211:8: note: declare 'static' if the function is not intended to be used outside of this translation unit
211 | __weak int __init numa_fill_memblks(u64 start, u64 end)
| ^
| static
6 warnings generated.
vim +/numa_fill_memblks +211 drivers/acpi/numa/srat.c
210
> 211 __weak int __init numa_fill_memblks(u64 start, u64 end)
212 {
213 return NUMA_NO_MEMBLK;
214 }
215
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki