]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl: Add callback to parse the DSMAS subtables from CDAT
authorDave Jiang <dave.jiang@intel.com>
Thu, 21 Dec 2023 22:03:13 +0000 (15:03 -0700)
committerDan Williams <dan.j.williams@intel.com>
Fri, 22 Dec 2023 22:33:10 +0000 (14:33 -0800)
Provide a callback function to the CDAT parser in order to parse the
Device Scoped Memory Affinity Structure (DSMAS). Each DSMAS structure
contains the DPA range and its associated attributes in each entry. See
the CDAT specification for details. The device handle and the DPA range
is saved and to be associated with the DSLBIS locality data when the
DSLBIS entries are parsed. The xarray is a local variable. When the
total path performance data is calculated and storred this xarray can be
discarded.

Coherent Device Attribute Table 1.03 2.1 Device Scoped memory Affinity
Structure (DSMAS)

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/170319619355.2212653.2675953129671561293.stgit@djiang5-mobl3
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/cxl/Kconfig
drivers/cxl/core/Makefile
drivers/cxl/core/cdat.c [new file with mode: 0644]
drivers/cxl/cxl.h
drivers/cxl/port.c
tools/testing/cxl/Kbuild

index 8ea1d340e4385089b3b449c07a0d6e1e679ab60a..67998dbd1d46b49dc623a0929c262174965bb601 100644 (file)
@@ -5,6 +5,7 @@ menuconfig CXL_BUS
        select FW_LOADER
        select FW_UPLOAD
        select PCI_DOE
+       select FIRMWARE_TABLE
        help
          CXL is a bus that is electrically compatible with PCI Express, but
          layers three protocols on that signalling (CXL.io, CXL.cache, and
@@ -54,8 +55,10 @@ config CXL_MEM_RAW_COMMANDS
 config CXL_ACPI
        tristate "CXL ACPI: Platform Support"
        depends on ACPI
+       depends on ACPI_NUMA
        default CXL_BUS
        select ACPI_TABLE_LIB
+       select ACPI_HMAT
        help
          Enable support for host managed device memory (HDM) resources
          published by a platform's ACPI CXL memory layout description.  See
index 1f66b5d4d93556868a5d413b520882f3d94b2f6f..9259bcc6773c804ccace2478c9f6f09267b48c9d 100644 (file)
@@ -13,5 +13,6 @@ cxl_core-y += mbox.o
 cxl_core-y += pci.o
 cxl_core-y += hdm.o
 cxl_core-y += pmu.o
+cxl_core-y += cdat.o
 cxl_core-$(CONFIG_TRACING) += trace.o
 cxl_core-$(CONFIG_CXL_REGION) += region.o
diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
new file mode 100644 (file)
index 0000000..9bf4f53
--- /dev/null
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2023 Intel Corporation. All rights reserved. */
+#include <linux/acpi.h>
+#include <linux/xarray.h>
+#include <linux/fw_table.h>
+#include "cxlpci.h"
+#include "cxl.h"
+
+struct dsmas_entry {
+       struct range dpa_range;
+       u8 handle;
+};
+
+static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
+                             const unsigned long end)
+{
+       struct acpi_cdat_header *hdr = &header->cdat;
+       struct acpi_cdat_dsmas *dsmas;
+       int size = sizeof(*hdr) + sizeof(*dsmas);
+       struct xarray *dsmas_xa = arg;
+       struct dsmas_entry *dent;
+       u16 len;
+       int rc;
+
+       len = le16_to_cpu((__force __le16)hdr->length);
+       if (len != size || (unsigned long)hdr + len > end) {
+               pr_warn("Malformed DSMAS table length: (%u:%u)\n", size, len);
+               return -EINVAL;
+       }
+
+       /* Skip common header */
+       dsmas = (struct acpi_cdat_dsmas *)(hdr + 1);
+
+       dent = kzalloc(sizeof(*dent), GFP_KERNEL);
+       if (!dent)
+               return -ENOMEM;
+
+       dent->handle = dsmas->dsmad_handle;
+       dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address);
+       dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) +
+                             le64_to_cpu((__force __le64)dsmas->dpa_length) - 1;
+
+       rc = xa_insert(dsmas_xa, dent->handle, dent, GFP_KERNEL);
+       if (rc) {
+               kfree(dent);
+               return rc;
+       }
+
+       return 0;
+}
+
+static int cxl_cdat_endpoint_process(struct cxl_port *port,
+                                    struct xarray *dsmas_xa)
+{
+       return cdat_table_parse(ACPI_CDAT_TYPE_DSMAS, cdat_dsmas_handler,
+                               dsmas_xa, port->cdat.table);
+}
+
+static void discard_dsmas(struct xarray *xa)
+{
+       unsigned long index;
+       void *ent;
+
+       xa_for_each(xa, index, ent) {
+               xa_erase(xa, index);
+               kfree(ent);
+       }
+       xa_destroy(xa);
+}
+DEFINE_FREE(dsmas, struct xarray *, if (_T) discard_dsmas(_T))
+
+void cxl_endpoint_parse_cdat(struct cxl_port *port)
+{
+       struct xarray __dsmas_xa;
+       struct xarray *dsmas_xa __free(dsmas) = &__dsmas_xa;
+       int rc;
+
+       xa_init(&__dsmas_xa);
+       if (!port->cdat.table)
+               return;
+
+       rc = cxl_cdat_endpoint_process(port, dsmas_xa);
+       if (rc < 0) {
+               dev_dbg(&port->dev, "Failed to parse CDAT: %d\n", rc);
+               return;
+       }
+
+       /* Performance data processing */
+}
+EXPORT_SYMBOL_NS_GPL(cxl_endpoint_parse_cdat, CXL);
+
+MODULE_IMPORT_NS(CXL);
index 687043ece1018c41c256c02cd697749d7916a42f..be3b5eda875c6d2a57dc0a6df3403d8e04c88ac5 100644 (file)
@@ -839,6 +839,8 @@ static inline struct cxl_dax_region *to_cxl_dax_region(struct device *dev)
 }
 #endif
 
+void cxl_endpoint_parse_cdat(struct cxl_port *port);
+
 /*
  * Unit test builds overrides this to __weak, find the 'strong' version
  * of these symbols in tools/testing/cxl/.
index 47bc8e0b859077776c06fc1daee901ab49cbdd2d..a889c4e6cb2721b1245a772cea1b8069eae9347a 100644 (file)
@@ -109,6 +109,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
 
        /* Cache the data early to ensure is_visible() works */
        read_cdat_data(port);
+       cxl_endpoint_parse_cdat(port);
 
        get_device(&cxlmd->dev);
        rc = devm_add_action_or_reset(&port->dev, schedule_detach, cxlmd);
index 95dc58b94178bf00b447b04440644bba1cd2209d..0b12c36902d82ddf23d8d71ac5067e282f1b1564 100644 (file)
@@ -58,6 +58,7 @@ cxl_core-y += $(CXL_CORE_SRC)/mbox.o
 cxl_core-y += $(CXL_CORE_SRC)/pci.o
 cxl_core-y += $(CXL_CORE_SRC)/hdm.o
 cxl_core-y += $(CXL_CORE_SRC)/pmu.o
+cxl_core-y += $(CXL_CORE_SRC)/cdat.o
 cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
 cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o
 cxl_core-y += config_check.o