Skip to content

Commit ad6f04c

Browse files
davejiangdjbw
authored andcommitted
cxl: Add callback to parse the DSMAS subtables from CDAT
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>
1 parent ca53543 commit ad6f04c

6 files changed

Lines changed: 100 additions & 0 deletions

File tree

drivers/cxl/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ menuconfig CXL_BUS
55
select FW_LOADER
66
select FW_UPLOAD
77
select PCI_DOE
8+
select FIRMWARE_TABLE
89
help
910
CXL is a bus that is electrically compatible with PCI Express, but
1011
layers three protocols on that signalling (CXL.io, CXL.cache, and
@@ -54,8 +55,10 @@ config CXL_MEM_RAW_COMMANDS
5455
config CXL_ACPI
5556
tristate "CXL ACPI: Platform Support"
5657
depends on ACPI
58+
depends on ACPI_NUMA
5759
default CXL_BUS
5860
select ACPI_TABLE_LIB
61+
select ACPI_HMAT
5962
help
6063
Enable support for host managed device memory (HDM) resources
6164
published by a platform's ACPI CXL memory layout description. See

drivers/cxl/core/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ cxl_core-y += mbox.o
1313
cxl_core-y += pci.o
1414
cxl_core-y += hdm.o
1515
cxl_core-y += pmu.o
16+
cxl_core-y += cdat.o
1617
cxl_core-$(CONFIG_TRACING) += trace.o
1718
cxl_core-$(CONFIG_CXL_REGION) += region.o

drivers/cxl/core/cdat.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright(c) 2023 Intel Corporation. All rights reserved. */
3+
#include <linux/acpi.h>
4+
#include <linux/xarray.h>
5+
#include <linux/fw_table.h>
6+
#include "cxlpci.h"
7+
#include "cxl.h"
8+
9+
struct dsmas_entry {
10+
struct range dpa_range;
11+
u8 handle;
12+
};
13+
14+
static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
15+
const unsigned long end)
16+
{
17+
struct acpi_cdat_header *hdr = &header->cdat;
18+
struct acpi_cdat_dsmas *dsmas;
19+
int size = sizeof(*hdr) + sizeof(*dsmas);
20+
struct xarray *dsmas_xa = arg;
21+
struct dsmas_entry *dent;
22+
u16 len;
23+
int rc;
24+
25+
len = le16_to_cpu((__force __le16)hdr->length);
26+
if (len != size || (unsigned long)hdr + len > end) {
27+
pr_warn("Malformed DSMAS table length: (%u:%u)\n", size, len);
28+
return -EINVAL;
29+
}
30+
31+
/* Skip common header */
32+
dsmas = (struct acpi_cdat_dsmas *)(hdr + 1);
33+
34+
dent = kzalloc(sizeof(*dent), GFP_KERNEL);
35+
if (!dent)
36+
return -ENOMEM;
37+
38+
dent->handle = dsmas->dsmad_handle;
39+
dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address);
40+
dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) +
41+
le64_to_cpu((__force __le64)dsmas->dpa_length) - 1;
42+
43+
rc = xa_insert(dsmas_xa, dent->handle, dent, GFP_KERNEL);
44+
if (rc) {
45+
kfree(dent);
46+
return rc;
47+
}
48+
49+
return 0;
50+
}
51+
52+
static int cxl_cdat_endpoint_process(struct cxl_port *port,
53+
struct xarray *dsmas_xa)
54+
{
55+
return cdat_table_parse(ACPI_CDAT_TYPE_DSMAS, cdat_dsmas_handler,
56+
dsmas_xa, port->cdat.table);
57+
}
58+
59+
static void discard_dsmas(struct xarray *xa)
60+
{
61+
unsigned long index;
62+
void *ent;
63+
64+
xa_for_each(xa, index, ent) {
65+
xa_erase(xa, index);
66+
kfree(ent);
67+
}
68+
xa_destroy(xa);
69+
}
70+
DEFINE_FREE(dsmas, struct xarray *, if (_T) discard_dsmas(_T))
71+
72+
void cxl_endpoint_parse_cdat(struct cxl_port *port)
73+
{
74+
struct xarray __dsmas_xa;
75+
struct xarray *dsmas_xa __free(dsmas) = &__dsmas_xa;
76+
int rc;
77+
78+
xa_init(&__dsmas_xa);
79+
if (!port->cdat.table)
80+
return;
81+
82+
rc = cxl_cdat_endpoint_process(port, dsmas_xa);
83+
if (rc < 0) {
84+
dev_dbg(&port->dev, "Failed to parse CDAT: %d\n", rc);
85+
return;
86+
}
87+
88+
/* Performance data processing */
89+
}
90+
EXPORT_SYMBOL_NS_GPL(cxl_endpoint_parse_cdat, CXL);
91+
92+
MODULE_IMPORT_NS(CXL);

drivers/cxl/cxl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,8 @@ static inline struct cxl_dax_region *to_cxl_dax_region(struct device *dev)
839839
}
840840
#endif
841841

842+
void cxl_endpoint_parse_cdat(struct cxl_port *port);
843+
842844
/*
843845
* Unit test builds overrides this to __weak, find the 'strong' version
844846
* of these symbols in tools/testing/cxl/.

drivers/cxl/port.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
109109

110110
/* Cache the data early to ensure is_visible() works */
111111
read_cdat_data(port);
112+
cxl_endpoint_parse_cdat(port);
112113

113114
get_device(&cxlmd->dev);
114115
rc = devm_add_action_or_reset(&port->dev, schedule_detach, cxlmd);

tools/testing/cxl/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ cxl_core-y += $(CXL_CORE_SRC)/mbox.o
5858
cxl_core-y += $(CXL_CORE_SRC)/pci.o
5959
cxl_core-y += $(CXL_CORE_SRC)/hdm.o
6060
cxl_core-y += $(CXL_CORE_SRC)/pmu.o
61+
cxl_core-y += $(CXL_CORE_SRC)/cdat.o
6162
cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
6263
cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o
6364
cxl_core-y += config_check.o

0 commit comments

Comments
 (0)