From: Alison Schofield <alison.schofield@intel.com>
To: Ben Widawsky <ben.widawsky@intel.com>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>,
Len Brown <lenb@kernel.org>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <ira.weiny@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
linux-cxl@vger.kernel.org, linux-acpi@vger.kernel.org
Subject: Re: [PATCH v2] ACPI: NUMA: Add a node and memblk for each CFMWS not in SRAT
Date: Mon, 18 Oct 2021 21:53:54 -0700 [thread overview]
Message-ID: <20211019045354.GA448935@alison-desk> (raw)
In-Reply-To: <20211019041039.goyz6wjo55ncgpmj@intel.com>
On Mon, Oct 18, 2021 at 09:10:39PM -0700, Ben Widawsky wrote:
> On 21-10-17 20:07:36, alison.schofield@intel.com wrote:
> > From: Alison Schofield <alison.schofield@intel.com>
> >
> > 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 <alison.schofield@intel.com>
> > ---
> >
> > Changes in v2:
> > - Use MAX_NUMNODES as max value when searching node_to_pxm_map() (0-day)
> > - Add braces around single statement for loop (coding style)
> > - Rename acpi_parse_cfmws() to acpi_cxl_cfmws_init to be more like other
> > functions in this file doing similar work.
> > - Comments: remove superflous and state importance of the init order,
> > CFMWS after SRAT, (Ira, Dan)
> > - Add prototype for numa_add_memblk() (0-day)
> >
> >
> > drivers/acpi/numa/srat.c | 70 ++++++++++++++++++++++++++++++++++++++++
> > drivers/cxl/acpi.c | 8 +++--
> > include/linux/acpi.h | 1 +
> > 3 files changed, 76 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
> > index b8795fc49097..4d26a4208af0 100644
> > --- a/drivers/acpi/numa/srat.c
> > +++ b/drivers/acpi/numa/srat.c
> > @@ -300,6 +300,67 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
> > }
> > #endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
> >
> > +static int __init acpi_cxl_cfmws_init(struct acpi_table_header *acpi_cedt)
> > +{
> > + struct acpi_cedt_cfmws *cfmws;
> > + acpi_size len, cur = 0;
> > + void *cedt_subtable;
> > + int i, pxm, node;
> > + u64 start, end;
> > +
> > + /* Find the max PXM defined in the SRAT */
> > + for (i = 0; i < MAX_NUMNODES - 1; i++) {
> > + if (node_to_pxm_map[i] > pxm)
>
> Doesn't pxm need to be initialized to something for this to work in the first
> iteration?
>
Thanks for the review Ben -
Yes. This needs to be initialized to 0. Behavior now is undefined, only zero
by chance.
> > + pxm = node_to_pxm_map[i];
> > + }
> > + /* Start assigning fake PXM values after the SRAT max PXM */
> > + pxm++;
> > +
> > + len = acpi_cedt->length - sizeof(*acpi_cedt);
> > + cedt_subtable = acpi_cedt + 1;
> > +
>
> Is there any way at all to share this with acpi.c from the CXL driver?
>
> > + while (cur < len) {
> > + struct acpi_cedt_header *c = cedt_subtable + cur;
> > +
> > + if (c->type != ACPI_CEDT_TYPE_CFMWS)
> > + goto next;
> > +
> > + cfmws = cedt_subtable + cur;
> > + if (cfmws->header.length < sizeof(*cfmws)) {
> > + pr_warn_once("CFMWS entry skipped:invalid length:%u\n",
> > + cfmws->header.length);
> > + goto next;
> > + }
> > +
> > + start = cfmws->base_hpa;
> > + end = cfmws->base_hpa + cfmws->window_size;
> > +
> > + /*
> > + * Skip if the SRAT already described
> > + * the NUMA details for this HPA.
> > + */
> > + node = phys_to_target_node(start);
> > + if (node != NUMA_NO_NODE)
> > + goto next;
> > +
> > + node = acpi_map_pxm_to_node(pxm);
> > + if (node == NUMA_NO_NODE) {
> > + pr_err("ACPI NUMA: Too many proximity domains.\n");
> > + return -EINVAL;
> > + }
> > +
> > + if (numa_add_memblk(node, start, end) < 0) {
> > + /* CXL driver must handle the NUMA_NO_NODE case */
> > + pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n",
> > + node, start, end);
> > + }
> > + pxm++;
> > +next:
> > + cur += c->length;
> > + }
> > + return 0;
> > +}
> > +
> > static int __init acpi_parse_slit(struct acpi_table_header *table)
> > {
> > struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
> > @@ -478,6 +539,15 @@ int __init acpi_numa_init(void)
> > /* SLIT: System Locality Information Table */
> > acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
> >
> > + /*
> > + * CEDT: CXL Fixed Memory Window Structures (CFMWS)
> > + * must be parsed after the SRAT. It creates NUMA
> > + * Nodes for CXL memory ranges not already defined
> > + * in the SRAT and it assigns PXMs after the max PXM
> > + * defined in the SRAT.
> > + */
> > + acpi_table_parse(ACPI_SIG_CEDT, acpi_cxl_cfmws_init);
> > +
> > if (cnt < 0)
> > return cnt;
> > else if (!parsed_numa_memblks)
> > diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
> > index 54e9d4d2cf5f..02f765a494b1 100644
> > --- a/drivers/cxl/acpi.c
> > +++ b/drivers/cxl/acpi.c
> > @@ -122,9 +122,11 @@ static void cxl_add_cfmws_decoders(struct device *dev,
> > cfmws->base_hpa, cfmws->base_hpa +
> > cfmws->window_size - 1);
> > } else {
> > - dev_dbg(dev, "add: %s range %#llx-%#llx\n",
> > - dev_name(&cxld->dev), cfmws->base_hpa,
> > - cfmws->base_hpa + cfmws->window_size - 1);
> > + dev_dbg(dev, "add: %s node: %d range %#llx-%#llx\n",
> > + dev_name(&cxld->dev),
> > + phys_to_target_node(cxld->range.start),
> > + cfmws->base_hpa,
> > + cfmws->base_hpa + cfmws->window_size - 1);
> > }
> > cur += c->length;
> > }
> > diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> > index 974d497a897d..f837fd715440 100644
> > --- a/include/linux/acpi.h
> > +++ b/include/linux/acpi.h
> > @@ -426,6 +426,7 @@ extern bool acpi_osi_is_win8(void);
> > #ifdef CONFIG_ACPI_NUMA
> > int acpi_map_pxm_to_node(int pxm);
> > int acpi_get_node(acpi_handle handle);
> > +int __init numa_add_memblk(int nodeid, u64 start, u64 end);
> >
> > /**
> > * pxm_to_online_node - Map proximity ID to online node
> >
> > base-commit: 64570fbc14f8d7cb3fe3995f20e26bc25ce4b2cc
> > --
> > 2.31.1
> >
prev parent reply other threads:[~2021-10-19 4:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-18 3:07 [PATCH v2] ACPI: NUMA: Add a node and memblk for each CFMWS not in SRAT alison.schofield
2021-10-19 4:10 ` Ben Widawsky
2021-10-19 4:53 ` Alison Schofield [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211019045354.GA448935@alison-desk \
--to=alison.schofield@intel.com \
--cc=ben.widawsky@intel.com \
--cc=dan.j.williams@intel.com \
--cc=ira.weiny@intel.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox