Message ID | 20240319120026.2246389-3-rrichter@amd.com |
---|---|
State | Superseded |
Headers | show |
Series | SRAT/CEDT fixes and updates | expand |
On Tue, Mar 19, 2024 at 01:00:24PM +0100, Robert Richter wrote: > The CEDT contains similar entries as the SRAT. For diagnostic reasons > print the CEDT same style as the SRAT. Richard, Acpitools is not properly handling the CFMWS at the moment. When that gets fixed up, might you be good using acpidump/extract. If you're going to dump, how about dumping it all? Add the fields interleave arithmetic, qtg_id, xormap_list[]. While debugging issues in this space I have wished for more info like this: 1) acpi_parse_cfmws() pr_warn's upon failure to add a node but is quiet on success. A pr_info on success, showing that a new memblk and node was added would be useful. 2) numa_add_memblks() if memblk was extended pr_info the info. If you can incorporate here, great! Thanks, Alison > > Signed-off-by: Robert Richter <rrichter@amd.com> > --- > drivers/acpi/numa/srat.c | 112 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 112 insertions(+) > > diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c > index e45e64993c50..50ae8557e8d1 100644 > --- a/drivers/acpi/numa/srat.c > +++ b/drivers/acpi/numa/srat.c > @@ -300,6 +300,114 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) > return -EINVAL; > } > > +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_info("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_info("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_info("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) > { > @@ -341,6 +449,7 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, > return 0; > } > #else > +static inline void acpi_table_print_cedt(void) {} > static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, > void *arg, const unsigned long table_end) > { > @@ -526,6 +635,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 >
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c index e45e64993c50..50ae8557e8d1 100644 --- a/drivers/acpi/numa/srat.c +++ b/drivers/acpi/numa/srat.c @@ -300,6 +300,114 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) return -EINVAL; } +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_info("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_info("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_info("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) { @@ -341,6 +449,7 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, return 0; } #else +static inline void acpi_table_print_cedt(void) {} static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, void *arg, const unsigned long table_end) { @@ -526,6 +635,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
The CEDT contains similar entries as the SRAT. For diagnostic reasons print the CEDT same style as the SRAT. Signed-off-by: Robert Richter <rrichter@amd.com> --- drivers/acpi/numa/srat.c | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+)