* [PATCH v5 00/27] cxl: add type2 device basic support
@ 2024-11-18 16:44 alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
` (27 more replies)
0 siblings, 28 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alejandro.lucero-palau@amd.com>
v5 changes:
- Fix SFC configuration based on kernel CXL configuration
- Add subset check for capabilities.
- fix region creation when HDM decoders programmed by firmware/BIOS (Ben
Cheatham)
- Add option for creating dax region based on driver decission (Ben
Cheatham)
- Using sfc probe_data struct for keeping sfc cxl data
v4 changes:
- Use bitmap for capabilities new field (Jonathan Cameron)
- Use cxl_mem attributes for sysfs based on device type (Dave Jian)
- Add conditional cxl sfc compilation relying on kernel CXL config (kernel test robot)
- Add sfc changes in different patches for facilitating backport (Jonathan Cameron)
- Remove patch for dealing with cxl modules dependencies and using sfc kconfig plus
MODULE_SOFTDEP instead.
v3 changes:
- cxl_dev_state not defined as opaque but only manipulated by accel drivers
through accessors.
- accessors names not identified as only for accel drivers.
- move pci code from pci driver (drivers/cxl/pci.c) to generic pci code
(drivers/cxl/core/pci.c).
- capabilities field from u8 to u32 and initialised by CXL regs discovering
code.
- add capabilities check and removing current check by CXL regs discovering
code.
- Not fail if CXL Device Registers not found. Not mandatory for Type2.
- add timeout in acquire_endpoint for solving a race with the endpoint port
creation.
- handle EPROBE_DEFER by sfc driver.
- Limiting interleave ways to 1 for accel driver HPA/DPA requests.
- factoring out interleave ways and granularity helpers from type2 region
creation patch.
- restricting region_creation for type2 to one endpoint decoder.
- add accessor for release_resource.
- handle errors and errors messages properly.
v2 changes:
I have removed the introduction about the concerns with BIOS/UEFI after the
discussion leading to confirm the need of the functionality implemented, at
least is some scenarios.
There are two main changes from the RFC:
1) Following concerns about drivers using CXL core without restrictions, the CXL
struct to work with is opaque to those drivers, therefore functions are
implemented for modifying or reading those structs indirectly.
2) The driver for using the added functionality is not a test driver but a real
one: the SFC ethernet network driver. It uses the CXL region mapped for PIO
buffers instead of regions inside PCIe BARs.
RFC:
Current CXL kernel code is focused on supporting Type3 CXL devices, aka memory
expanders. Type2 CXL devices, aka device accelerators, share some functionalities
but require some special handling.
First of all, Type2 are by definition specific to drivers doing something and not just
a memory expander, so it is expected to work with the CXL specifics. This implies the CXL
setup needs to be done by such a driver instead of by a generic CXL PCI driver
as for memory expanders. Most of such setup needs to use current CXL core code
and therefore needs to be accessible to those vendor drivers. This is accomplished
exporting opaque CXL structs and adding and exporting functions for working with
those structs indirectly.
Some of the patches are based on a patchset sent by Dan Williams [1] which was just
partially integrated, most related to making things ready for Type2 but none
related to specific Type2 support. Those patches based on Dan´s work have Dan´s
signing as co-developer, and a link to the original patch.
A final note about CXL.cache is needed. This patchset does not cover it at all,
although the emulated Type2 device advertises it. From the kernel point of view
supporting CXL.cache will imply to be sure the CXL path supports what the Type2
device needs. A device accelerator will likely be connected to a Root Switch,
but other configurations can not be discarded. Therefore the kernel will need to
check not just HPA, DPA, interleave and granularity, but also the available
CXL.cache support and resources in each switch in the CXL path to the Type2
device. I expect to contribute to this support in the following months, and
it would be good to discuss about it when possible.
[1] https://lore.kernel.org/linux-cxl/98b1f61a-e6c2-71d4-c368-50d958501b0c@intel.com/T/
Alejandro Lucero (27):
cxl: add type2 device basic support
sfc: add cxl support using new CXL API
cxl: add capabilities field to cxl_dev_state and cxl_port
cxl/pci: add check for validating capabilities
cxl: move pci generic code
cxl: add function for type2 cxl regs setup
sfc: use cxl api for regs setup and checking
cxl: add functions for resource request/release by a driver
sfc: request cxl ram resource
cxl: harden resource_contains checks to handle zero size resources
cxl: add function for setting media ready by a driver
sfc: set cxl media ready
cxl: prepare memdev creation for type2
sfc: create type2 cxl memdev
cxl: define a driver interface for HPA free space enumeration
sfc: obtain root decoder with enough HPA free space
cxl: define a driver interface for DPA allocation
sfc: get endpoint decoder
cxl: make region type based on endpoint type
cxl/region: factor out interleave ways setup
cxl/region: factor out interleave granularity setup
cxl: allow region creation by type2 drivers
sfc: create cxl region
cxl: add region flag for precluding a device memory to be used for dax
sfc: specify avoid dax when cxl region is created
cxl: add function for obtaining params from a region
sfc: support pio mapping based on cxl
drivers/cxl/core/cdat.c | 3 +
drivers/cxl/core/hdm.c | 160 ++++++++--
drivers/cxl/core/memdev.c | 123 +++++++-
drivers/cxl/core/pci.c | 132 ++++++++
drivers/cxl/core/port.c | 11 +-
drivers/cxl/core/region.c | 414 ++++++++++++++++++++++----
drivers/cxl/core/regs.c | 30 +-
drivers/cxl/cxl.h | 17 +-
drivers/cxl/cxlmem.h | 5 +
drivers/cxl/cxlpci.h | 19 +-
drivers/cxl/mem.c | 25 +-
drivers/cxl/pci.c | 99 +++---
drivers/cxl/port.c | 5 +-
drivers/net/ethernet/sfc/Kconfig | 7 +
drivers/net/ethernet/sfc/Makefile | 1 +
drivers/net/ethernet/sfc/ef10.c | 49 ++-
drivers/net/ethernet/sfc/efx.c | 24 +-
drivers/net/ethernet/sfc/efx_cxl.c | 181 +++++++++++
drivers/net/ethernet/sfc/efx_cxl.h | 28 ++
drivers/net/ethernet/sfc/mcdi_pcol.h | 12 +
drivers/net/ethernet/sfc/net_driver.h | 12 +
drivers/net/ethernet/sfc/nic.h | 3 +
include/cxl/cxl.h | 82 +++++
include/cxl/pci.h | 23 ++
24 files changed, 1269 insertions(+), 196 deletions(-)
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
create mode 100644 include/cxl/cxl.h
create mode 100644 include/cxl/pci.h
--
2.17.1
^ permalink raw reply [flat|nested] 99+ messages in thread
* [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 21:55 ` Dave Jiang
` (3 more replies)
2024-11-18 16:44 ` [PATCH v5 02/27] sfc: add cxl support using new CXL API alejandro.lucero-palau
` (26 subsequent siblings)
27 siblings, 4 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Differentiate Type3, aka memory expanders, from Type2, aka device
accelerators, with a new function for initializing cxl_dev_state.
Create accessors to cxl_dev_state to be used by accel drivers.
Based on previous work by Dan Williams [1]
Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Co-developed-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
drivers/cxl/core/pci.c | 1 +
drivers/cxl/cxlpci.h | 16 ------------
drivers/cxl/pci.c | 13 +++++++---
include/cxl/cxl.h | 21 ++++++++++++++++
include/cxl/pci.h | 23 ++++++++++++++++++
6 files changed, 105 insertions(+), 20 deletions(-)
create mode 100644 include/cxl/cxl.h
create mode 100644 include/cxl/pci.h
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 84fefb76dafa..d083fd13a6dd 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2020 Intel Corporation. */
+#include <cxl/cxl.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/firmware.h>
#include <linux/device.h>
@@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
static struct lock_class_key cxl_memdev_key;
+struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
+{
+ struct cxl_dev_state *cxlds;
+
+ cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
+ if (!cxlds)
+ return ERR_PTR(-ENOMEM);
+
+ cxlds->dev = dev;
+ cxlds->type = CXL_DEVTYPE_DEVMEM;
+
+ cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
+ cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
+ cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
+
+ return cxlds;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
+
static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
const struct file_operations *fops)
{
@@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
return 0;
}
+void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
+{
+ cxlds->cxl_dvsec = dvsec;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
+
+void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
+{
+ cxlds->serial = serial;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
+
+int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
+ enum cxl_resource type)
+{
+ switch (type) {
+ case CXL_RES_DPA:
+ cxlds->dpa_res = res;
+ return 0;
+ case CXL_RES_RAM:
+ cxlds->ram_res = res;
+ return 0;
+ case CXL_RES_PMEM:
+ cxlds->pmem_res = res;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
+
static int cxl_memdev_release_file(struct inode *inode, struct file *file)
{
struct cxl_memdev *cxlmd =
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 420e4be85a1f..ff266e91ea71 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2021 Intel Corporation. All rights reserved. */
+#include <cxl/pci.h>
#include <linux/units.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/device.h>
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index 4da07727ab9c..eb59019fe5f3 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -14,22 +14,6 @@
*/
#define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
-/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
-#define CXL_DVSEC_PCIE_DEVICE 0
-#define CXL_DVSEC_CAP_OFFSET 0xA
-#define CXL_DVSEC_MEM_CAPABLE BIT(2)
-#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
-#define CXL_DVSEC_CTRL_OFFSET 0xC
-#define CXL_DVSEC_MEM_ENABLE BIT(2)
-#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
-#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
-#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
-#define CXL_DVSEC_MEM_ACTIVE BIT(1)
-#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
-#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
-#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
-#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
-
#define CXL_DVSEC_RANGE_MAX 2
/* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 188412d45e0d..0b910ef52db7 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+#include <cxl/cxl.h>
+#include <cxl/pci.h>
#include <linux/unaligned.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/moduleparam.h>
@@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct cxl_memdev *cxlmd;
int i, rc, pmu_count;
bool irq_avail;
+ u16 dvsec;
/*
* Double check the anonymous union trickery in struct cxl_regs
@@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, cxlds);
cxlds->rcd = is_cxl_restricted(pdev);
- cxlds->serial = pci_get_dsn(pdev);
- cxlds->cxl_dvsec = pci_find_dvsec_capability(
- pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
- if (!cxlds->cxl_dvsec)
+ cxl_set_serial(cxlds, pci_get_dsn(pdev));
+ dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
+ CXL_DVSEC_PCIE_DEVICE);
+ if (!dvsec)
dev_warn(&pdev->dev,
"Device DVSEC not present, skip CXL.mem init\n");
+ cxl_set_dvsec(cxlds, dvsec);
+
rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
if (rc)
return rc;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
new file mode 100644
index 000000000000..19e5d883557a
--- /dev/null
+++ b/include/cxl/cxl.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
+
+#ifndef __CXL_H
+#define __CXL_H
+
+#include <linux/ioport.h>
+
+enum cxl_resource {
+ CXL_RES_DPA,
+ CXL_RES_RAM,
+ CXL_RES_PMEM,
+};
+
+struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
+
+void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
+void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
+int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
+ enum cxl_resource);
+#endif
diff --git a/include/cxl/pci.h b/include/cxl/pci.h
new file mode 100644
index 000000000000..ad63560caa2c
--- /dev/null
+++ b/include/cxl/pci.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+
+#ifndef __CXL_ACCEL_PCI_H
+#define __CXL_ACCEL_PCI_H
+
+/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
+#define CXL_DVSEC_PCIE_DEVICE 0
+#define CXL_DVSEC_CAP_OFFSET 0xA
+#define CXL_DVSEC_MEM_CAPABLE BIT(2)
+#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
+#define CXL_DVSEC_CTRL_OFFSET 0xC
+#define CXL_DVSEC_MEM_ENABLE BIT(2)
+#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
+#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
+#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
+#define CXL_DVSEC_MEM_ACTIVE BIT(1)
+#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
+#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
+#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
+#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
+
+#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 02/27] sfc: add cxl support using new CXL API
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-22 20:43 ` Ben Cheatham
2024-11-26 18:08 ` Fan Ni
2024-11-18 16:44 ` [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port alejandro.lucero-palau
` (25 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Add CXL initialization based on new CXL API for accel drivers and make
it dependable on kernel CXL configuration.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/Kconfig | 7 +++
drivers/net/ethernet/sfc/Makefile | 1 +
drivers/net/ethernet/sfc/efx.c | 24 +++++++-
drivers/net/ethernet/sfc/efx_cxl.c | 88 +++++++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_cxl.h | 28 +++++++++
drivers/net/ethernet/sfc/net_driver.h | 10 +++
6 files changed, 157 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 3eb55dcfa8a6..a8bc777baa95 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -65,6 +65,13 @@ config SFC_MCDI_LOGGING
Driver-Interface) commands and responses, allowing debugging of
driver/firmware interaction. The tracing is actually enabled by
a sysfs file 'mcdi_logging' under the PCI device.
+config SFC_CXL
+ bool "Solarflare SFC9100-family CXL support"
+ depends on SFC && CXL_BUS && !(SFC=y && CXL_BUS=m)
+ default y
+ help
+ This enables CXL support by the driver relying on kernel support
+ and hardware support.
source "drivers/net/ethernet/sfc/falcon/Kconfig"
source "drivers/net/ethernet/sfc/siena/Kconfig"
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
index 8f446b9bd5ee..e909cafd5908 100644
--- a/drivers/net/ethernet/sfc/Makefile
+++ b/drivers/net/ethernet/sfc/Makefile
@@ -13,6 +13,7 @@ sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
mae.o tc.o tc_bindings.o tc_counters.o \
tc_encap_actions.o tc_conntrack.o
+sfc-$(CONFIG_SFC_CXL) += efx_cxl.o
obj-$(CONFIG_SFC) += sfc.o
obj-$(CONFIG_SFC_FALCON) += falcon/
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 36b3b57e2055..5f7c910a14a5 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -33,6 +33,9 @@
#include "selftest.h"
#include "sriov.h"
#include "efx_devlink.h"
+#ifdef CONFIG_SFC_CXL
+#include "efx_cxl.h"
+#endif
#include "mcdi_port_common.h"
#include "mcdi_pcol.h"
@@ -903,12 +906,17 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_pci_remove_main(efx);
efx_fini_io(efx);
+
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+#ifdef CONFIG_SFC_CXL
+ efx_cxl_exit(probe_data);
+#endif
+
pci_dbg(efx->pci_dev, "shutdown successful\n");
efx_fini_devlink_and_unlock(efx);
efx_fini_struct(efx);
free_netdev(efx->net_dev);
- probe_data = container_of(efx, struct efx_probe_data, efx);
kfree(probe_data);
};
@@ -1113,6 +1121,17 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
if (rc)
goto fail2;
+#ifdef CONFIG_SFC_CXL
+ /* A successful cxl initialization implies a CXL region created to be
+ * used for PIO buffers. If there is no CXL support, or initialization
+ * fails, efx_cxl_pio_initialised wll be false and legacy PIO buffers
+ * defined at specific PCI BAR regions will be used.
+ */
+ rc = efx_cxl_init(probe_data);
+ if (rc)
+ pci_err(pci_dev, "CXL initialization failed with error %d\n", rc);
+
+#endif
rc = efx_pci_probe_post_io(efx);
if (rc) {
/* On failure, retry once immediately.
@@ -1384,3 +1403,6 @@ MODULE_AUTHOR("Solarflare Communications and "
MODULE_DESCRIPTION("Solarflare network driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, efx_pci_table);
+#ifdef CONFIG_SFC_CXL
+MODULE_SOFTDEP("pre: cxl_core cxl_port cxl_acpi cxl-mem");
+#endif
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
new file mode 100644
index 000000000000..99f396028639
--- /dev/null
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ *
+ * Driver for AMD network controllers and boards
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include <cxl/cxl.h>
+#include <cxl/pci.h>
+#include <linux/pci.h>
+
+#include "net_driver.h"
+#include "efx_cxl.h"
+
+#define EFX_CTPIO_BUFFER_SIZE SZ_256M
+
+int efx_cxl_init(struct efx_probe_data *probe_data)
+{
+ struct efx_nic *efx = &probe_data->efx;
+ struct pci_dev *pci_dev;
+ struct efx_cxl *cxl;
+ struct resource res;
+ u16 dvsec;
+ int rc;
+
+ pci_dev = efx->pci_dev;
+ probe_data->cxl_pio_initialised = false;
+
+ dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
+ CXL_DVSEC_PCIE_DEVICE);
+ if (!dvsec)
+ return 0;
+
+ pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
+
+ cxl = kzalloc(sizeof(*cxl), GFP_KERNEL);
+ if (!cxl)
+ return -ENOMEM;
+
+ cxl->cxlds = cxl_accel_state_create(&pci_dev->dev);
+ if (IS_ERR(cxl->cxlds)) {
+ pci_err(pci_dev, "CXL accel device state failed");
+ rc = -ENOMEM;
+ goto err1;
+ }
+
+ cxl_set_dvsec(cxl->cxlds, dvsec);
+ cxl_set_serial(cxl->cxlds, pci_dev->dev.id);
+
+ res = DEFINE_RES_MEM(0, EFX_CTPIO_BUFFER_SIZE);
+ if (cxl_set_resource(cxl->cxlds, res, CXL_RES_DPA)) {
+ pci_err(pci_dev, "cxl_set_resource DPA failed\n");
+ rc = -EINVAL;
+ goto err2;
+ }
+
+ res = DEFINE_RES_MEM_NAMED(0, EFX_CTPIO_BUFFER_SIZE, "ram");
+ if (cxl_set_resource(cxl->cxlds, res, CXL_RES_RAM)) {
+ pci_err(pci_dev, "cxl_set_resource RAM failed\n");
+ rc = -EINVAL;
+ goto err2;
+ }
+
+ probe_data->cxl = cxl;
+
+ return 0;
+
+err2:
+ kfree(cxl->cxlds);
+err1:
+ kfree(cxl);
+ return rc;
+
+}
+
+void efx_cxl_exit(struct efx_probe_data *probe_data)
+{
+ if (probe_data->cxl) {
+ kfree(probe_data->cxl->cxlds);
+ kfree(probe_data->cxl);
+ }
+}
+
+MODULE_IMPORT_NS(CXL);
diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
new file mode 100644
index 000000000000..90fa46bc94db
--- /dev/null
+++ b/drivers/net/ethernet/sfc/efx_cxl.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for AMD network controllers and boards
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_CXL_H
+#define EFX_CXL_H
+
+struct efx_nic;
+
+struct efx_cxl {
+ struct cxl_dev_state *cxlds;
+ struct cxl_memdev *cxlmd;
+ struct cxl_root_decoder *cxlrd;
+ struct cxl_port *endpoint;
+ struct cxl_endpoint_decoder *cxled;
+ struct cxl_region *efx_region;
+ void __iomem *ctpio_cxl;
+};
+
+int efx_cxl_init(struct efx_probe_data *probe_data);
+void efx_cxl_exit(struct efx_probe_data *probe_data);
+#endif
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index b85c51cbe7f9..efc6d90380b9 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1160,14 +1160,24 @@ struct efx_nic {
atomic_t n_rx_noskb_drops;
};
+#ifdef CONFIG_SFC_CXL
+struct efx_cxl;
+#endif
+
/**
* struct efx_probe_data - State after hardware probe
* @pci_dev: The PCI device
* @efx: Efx NIC details
+ * @cxl: details of related cxl objects
+ * @cxl_pio_initialised: cxl initialization outcome.
*/
struct efx_probe_data {
struct pci_dev *pci_dev;
struct efx_nic efx;
+#ifdef CONFIG_SFC_CXL
+ struct efx_cxl *cxl;
+ bool cxl_pio_initialised;
+#endif
};
static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 02/27] sfc: add cxl support using new CXL API alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 22:52 ` Dave Jiang
2024-11-22 20:44 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 04/27] cxl/pci: add check for validating capabilities alejandro.lucero-palau
` (24 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Type2 devices have some Type3 functionalities as optional like an mbox
or an hdm decoder, and CXL core needs a way to know what an CXL accelerator
implements.
Add a new field to cxl_dev_state for keeping device capabilities as discovered
during initialization. Add same field to cxl_port as registers discovery
is also used during port initialization.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/port.c | 11 +++++++----
drivers/cxl/core/regs.c | 21 ++++++++++++++-------
drivers/cxl/cxl.h | 9 ++++++---
drivers/cxl/cxlmem.h | 2 ++
drivers/cxl/pci.c | 10 ++++++----
include/cxl/cxl.h | 30 ++++++++++++++++++++++++++++++
6 files changed, 65 insertions(+), 18 deletions(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index af92c67bc954..5bc8490a199c 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -749,7 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
}
static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map,
- resource_size_t component_reg_phys)
+ resource_size_t component_reg_phys, unsigned long *caps)
{
*map = (struct cxl_register_map) {
.host = host,
@@ -763,7 +763,7 @@ static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map
map->reg_type = CXL_REGLOC_RBI_COMPONENT;
map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
- return cxl_setup_regs(map);
+ return cxl_setup_regs(map, caps);
}
static int cxl_port_setup_regs(struct cxl_port *port,
@@ -772,7 +772,7 @@ static int cxl_port_setup_regs(struct cxl_port *port,
if (dev_is_platform(port->uport_dev))
return 0;
return cxl_setup_comp_regs(&port->dev, &port->reg_map,
- component_reg_phys);
+ component_reg_phys, port->capabilities);
}
static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
@@ -789,7 +789,8 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
* NULL.
*/
rc = cxl_setup_comp_regs(dport->dport_dev, &dport->reg_map,
- component_reg_phys);
+ component_reg_phys,
+ dport->port->capabilities);
dport->reg_map.host = host;
return rc;
}
@@ -851,6 +852,8 @@ static int cxl_port_add(struct cxl_port *port,
port->reg_map = cxlds->reg_map;
port->reg_map.host = &port->dev;
cxlmd->endpoint = port;
+ bitmap_copy(port->capabilities, cxlds->capabilities,
+ CXL_MAX_CAPS);
} else if (parent_dport) {
rc = dev_set_name(dev, "port%d", port->id);
if (rc)
diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
index e1082e749c69..8287ec45b018 100644
--- a/drivers/cxl/core/regs.c
+++ b/drivers/cxl/core/regs.c
@@ -4,6 +4,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <cxl/cxl.h>
#include <cxlmem.h>
#include <cxlpci.h>
#include <pmu.h>
@@ -36,7 +37,8 @@
* Probe for component register information and return it in map object.
*/
void cxl_probe_component_regs(struct device *dev, void __iomem *base,
- struct cxl_component_reg_map *map)
+ struct cxl_component_reg_map *map,
+ unsigned long *caps)
{
int cap, cap_count;
u32 cap_array;
@@ -84,6 +86,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
decoder_cnt = cxl_hdm_decoder_count(hdr);
length = 0x20 * decoder_cnt + 0x10;
rmap = &map->hdm_decoder;
+ *caps |= BIT(CXL_DEV_CAP_HDM);
break;
}
case CXL_CM_CAP_CAP_ID_RAS:
@@ -91,6 +94,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
offset);
length = CXL_RAS_CAPABILITY_LENGTH;
rmap = &map->ras;
+ *caps |= BIT(CXL_DEV_CAP_RAS);
break;
default:
dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
@@ -117,7 +121,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);
* Probe for device register information and return it in map object.
*/
void cxl_probe_device_regs(struct device *dev, void __iomem *base,
- struct cxl_device_reg_map *map)
+ struct cxl_device_reg_map *map, unsigned long *caps)
{
int cap, cap_count;
u64 cap_array;
@@ -146,10 +150,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
dev_dbg(dev, "found Status capability (0x%x)\n", offset);
rmap = &map->status;
+ *caps |= BIT(CXL_DEV_CAP_DEV_STATUS);
break;
case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
rmap = &map->mbox;
+ *caps |= BIT(CXL_DEV_CAP_MAILBOX_PRIMARY);
break;
case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
@@ -157,6 +163,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
case CXLDEV_CAP_CAP_ID_MEMDEV:
dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
rmap = &map->memdev;
+ *caps |= BIT(CXL_DEV_CAP_MEMDEV);
break;
default:
if (cap_id >= 0x8000)
@@ -421,7 +428,7 @@ static void cxl_unmap_regblock(struct cxl_register_map *map)
map->base = NULL;
}
-static int cxl_probe_regs(struct cxl_register_map *map)
+static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
{
struct cxl_component_reg_map *comp_map;
struct cxl_device_reg_map *dev_map;
@@ -431,12 +438,12 @@ static int cxl_probe_regs(struct cxl_register_map *map)
switch (map->reg_type) {
case CXL_REGLOC_RBI_COMPONENT:
comp_map = &map->component_map;
- cxl_probe_component_regs(host, base, comp_map);
+ cxl_probe_component_regs(host, base, comp_map, caps);
dev_dbg(host, "Set up component registers\n");
break;
case CXL_REGLOC_RBI_MEMDEV:
dev_map = &map->device_map;
- cxl_probe_device_regs(host, base, dev_map);
+ cxl_probe_device_regs(host, base, dev_map, caps);
if (!dev_map->status.valid || !dev_map->mbox.valid ||
!dev_map->memdev.valid) {
dev_err(host, "registers not found: %s%s%s\n",
@@ -455,7 +462,7 @@ static int cxl_probe_regs(struct cxl_register_map *map)
return 0;
}
-int cxl_setup_regs(struct cxl_register_map *map)
+int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps)
{
int rc;
@@ -463,7 +470,7 @@ int cxl_setup_regs(struct cxl_register_map *map)
if (rc)
return rc;
- rc = cxl_probe_regs(map);
+ rc = cxl_probe_regs(map, caps);
cxl_unmap_regblock(map);
return rc;
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index a2be05fd7aa2..e5f918be6fe4 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -4,6 +4,7 @@
#ifndef __CXL_H__
#define __CXL_H__
+#include <cxl/cxl.h>
#include <linux/libnvdimm.h>
#include <linux/bitfield.h>
#include <linux/notifier.h>
@@ -284,9 +285,9 @@ struct cxl_register_map {
};
void cxl_probe_component_regs(struct device *dev, void __iomem *base,
- struct cxl_component_reg_map *map);
+ struct cxl_component_reg_map *map, unsigned long *caps);
void cxl_probe_device_regs(struct device *dev, void __iomem *base,
- struct cxl_device_reg_map *map);
+ struct cxl_device_reg_map *map, unsigned long *caps);
int cxl_map_component_regs(const struct cxl_register_map *map,
struct cxl_component_regs *regs,
unsigned long map_mask);
@@ -300,7 +301,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
struct cxl_register_map *map, int index);
int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
struct cxl_register_map *map);
-int cxl_setup_regs(struct cxl_register_map *map);
+int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps);
struct cxl_dport;
resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
struct cxl_dport *dport);
@@ -600,6 +601,7 @@ struct cxl_dax_region {
* @cdat: Cached CDAT data
* @cdat_available: Should a CDAT attribute be available in sysfs
* @pci_latency: Upstream latency in picoseconds
+ * @capabilities: those capabilities as defined in device mapped registers
*/
struct cxl_port {
struct device dev;
@@ -623,6 +625,7 @@ struct cxl_port {
} cdat;
bool cdat_available;
long pci_latency;
+ DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
};
/**
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 2a25d1957ddb..4c1c53c29544 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -428,6 +428,7 @@ struct cxl_dpa_perf {
* @serial: PCIe Device Serial Number
* @type: Generic Memory Class device or Vendor Specific Memory device
* @cxl_mbox: CXL mailbox context
+ * @capabilities: those capabilities as defined in device mapped registers
*/
struct cxl_dev_state {
struct device *dev;
@@ -443,6 +444,7 @@ struct cxl_dev_state {
u64 serial;
enum cxl_devtype type;
struct cxl_mailbox cxl_mbox;
+ DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
};
static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 0b910ef52db7..528d4ca79fd1 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -504,7 +504,8 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
}
static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
- struct cxl_register_map *map)
+ struct cxl_register_map *map,
+ unsigned long *caps)
{
int rc;
@@ -521,7 +522,7 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
if (rc)
return rc;
- return cxl_setup_regs(map);
+ return cxl_setup_regs(map, caps);
}
static int cxl_pci_ras_unmask(struct pci_dev *pdev)
@@ -848,7 +849,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
cxl_set_dvsec(cxlds, dvsec);
- rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
+ rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
+ cxlds->capabilities);
if (rc)
return rc;
@@ -861,7 +863,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
* still be useful for management functions so don't return an error.
*/
rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
- &cxlds->reg_map);
+ &cxlds->reg_map, cxlds->capabilities);
if (rc)
dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
else if (!cxlds->reg_map.component_map.ras.valid)
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 19e5d883557a..dcc9ec8a0aec 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -12,6 +12,36 @@ enum cxl_resource {
CXL_RES_PMEM,
};
+/* Capabilities as defined for:
+ *
+ * Component Registers (Table 8-22 CXL 3.1 specification)
+ * Device Registers (8.2.8.2.1 CXL 3.1 specification)
+ */
+
+enum cxl_dev_cap {
+ /* capabilities from Component Registers */
+ CXL_DEV_CAP_RAS,
+ CXL_DEV_CAP_SEC,
+ CXL_DEV_CAP_LINK,
+ CXL_DEV_CAP_HDM,
+ CXL_DEV_CAP_SEC_EXT,
+ CXL_DEV_CAP_IDE,
+ CXL_DEV_CAP_SNOOP_FILTER,
+ CXL_DEV_CAP_TIMEOUT_AND_ISOLATION,
+ CXL_DEV_CAP_CACHEMEM_EXT,
+ CXL_DEV_CAP_BI_ROUTE_TABLE,
+ CXL_DEV_CAP_BI_DECODER,
+ CXL_DEV_CAP_CACHEID_ROUTE_TABLE,
+ CXL_DEV_CAP_CACHEID_DECODER,
+ CXL_DEV_CAP_HDM_EXT,
+ CXL_DEV_CAP_METADATA_EXT,
+ /* capabilities from Device Registers */
+ CXL_DEV_CAP_DEV_STATUS,
+ CXL_DEV_CAP_MAILBOX_PRIMARY,
+ CXL_DEV_CAP_MEMDEV,
+ CXL_MAX_CAPS = 32
+};
+
struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 04/27] cxl/pci: add check for validating capabilities
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (2 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-22 20:44 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 05/27] cxl: move pci generic code alejandro.lucero-palau
` (23 subsequent siblings)
27 siblings, 1 reply; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
During CXL device initialization supported capabilities by the device
are discovered. Type3 and Type2 devices have different mandatory
capabilities and a Type2 expects a specific set including optional
capabilities.
Add a function for checking expected capabilities against those found
during initialization. Allow those mandatory/expected capabilities to
be a subset of the capabilities found.
Rely on this function for validating capabilities instead of when CXL
regs are probed.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/pci.c | 22 ++++++++++++++++++++++
drivers/cxl/core/regs.c | 9 ---------
drivers/cxl/pci.c | 24 ++++++++++++++++++++++++
include/cxl/cxl.h | 6 +++++-
4 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index ff266e91ea71..a1942b7be0bc 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -8,6 +8,7 @@
#include <linux/pci.h>
#include <linux/pci-doe.h>
#include <linux/aer.h>
+#include <cxl/cxl.h>
#include <cxlpci.h>
#include <cxlmem.h>
#include <cxl.h>
@@ -1055,3 +1056,24 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
return 0;
}
+
+bool cxl_pci_check_caps(struct cxl_dev_state *cxlds, unsigned long *expected_caps,
+ unsigned long *current_caps, bool is_subset)
+{
+ DECLARE_BITMAP(subset, CXL_MAX_CAPS);
+
+ if (current_caps)
+ bitmap_copy(current_caps, cxlds->capabilities, CXL_MAX_CAPS);
+
+ dev_dbg(cxlds->dev, "Checking cxlds caps 0x%08lx vs expected caps 0x%08lx\n",
+ *cxlds->capabilities, *expected_caps);
+
+ /* Checking a minimum of mandatory capabilities? */
+ if (is_subset) {
+ bitmap_and(subset, cxlds->capabilities, expected_caps, CXL_MAX_CAPS);
+ return bitmap_equal(subset, expected_caps, CXL_MAX_CAPS);
+ } else {
+ return bitmap_equal(cxlds->capabilities, expected_caps, CXL_MAX_CAPS);
+ }
+}
+EXPORT_SYMBOL_NS_GPL(cxl_pci_check_caps, CXL);
diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
index 8287ec45b018..3b3965706414 100644
--- a/drivers/cxl/core/regs.c
+++ b/drivers/cxl/core/regs.c
@@ -444,15 +444,6 @@ static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
case CXL_REGLOC_RBI_MEMDEV:
dev_map = &map->device_map;
cxl_probe_device_regs(host, base, dev_map, caps);
- if (!dev_map->status.valid || !dev_map->mbox.valid ||
- !dev_map->memdev.valid) {
- dev_err(host, "registers not found: %s%s%s\n",
- !dev_map->status.valid ? "status " : "",
- !dev_map->mbox.valid ? "mbox " : "",
- !dev_map->memdev.valid ? "memdev " : "");
- return -ENXIO;
- }
-
dev_dbg(host, "Probing device registers...\n");
break;
default:
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 528d4ca79fd1..5de1473a79da 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -813,6 +813,8 @@ static int cxl_pci_type3_init_mailbox(struct cxl_dev_state *cxlds)
static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
+ DECLARE_BITMAP(expected, CXL_MAX_CAPS);
+ DECLARE_BITMAP(found, CXL_MAX_CAPS);
struct cxl_memdev_state *mds;
struct cxl_dev_state *cxlds;
struct cxl_register_map map;
@@ -874,6 +876,28 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
+ bitmap_clear(expected, 0, CXL_MAX_CAPS);
+
+ /*
+ * These are the mandatory capabilities for a Type3 device.
+ * Only checking capabilities used by current Linux drivers.
+ */
+ bitmap_set(expected, CXL_DEV_CAP_HDM, 1);
+ bitmap_set(expected, CXL_DEV_CAP_DEV_STATUS, 1);
+ bitmap_set(expected, CXL_DEV_CAP_MAILBOX_PRIMARY, 1);
+ bitmap_set(expected, CXL_DEV_CAP_DEV_STATUS, 1);
+
+ /*
+ * Checking mandatory caps are there as, at least, a subset of those
+ * found.
+ */
+ if (!cxl_pci_check_caps(cxlds, expected, found, true)) {
+ dev_err(&pdev->dev,
+ "Expected mandatory capabilities not found: (%08lx - %08lx)\n",
+ *expected, *found);
+ return -ENXIO;
+ }
+
rc = cxl_pci_type3_init_mailbox(cxlds);
if (rc)
return rc;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index dcc9ec8a0aec..ab243ab8024f 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -39,7 +39,7 @@ enum cxl_dev_cap {
CXL_DEV_CAP_DEV_STATUS,
CXL_DEV_CAP_MAILBOX_PRIMARY,
CXL_DEV_CAP_MEMDEV,
- CXL_MAX_CAPS = 32
+ CXL_MAX_CAPS = 64
};
struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
@@ -48,4 +48,8 @@ void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
enum cxl_resource);
+bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
+ unsigned long *expected_caps,
+ unsigned long *current_caps,
+ bool is_subset);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 05/27] cxl: move pci generic code
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (3 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 04/27] cxl/pci: add check for validating capabilities alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 22:57 ` Dave Jiang
2024-11-22 20:44 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 06/27] cxl: add function for type2 cxl regs setup alejandro.lucero-palau
` (22 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Inside cxl/core/pci.c there are helpers for CXL PCIe initialization
meanwhile cxl/pci.c implements the functionality for a Type3 device
initialization.
Move helper functions from cxl/pci.c to cxl/core/pci.c in order to be
exported and shared with CXL Type2 device initialization.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/pci.c | 62 ++++++++++++++++++++++++++++++++++++++++++
drivers/cxl/cxlpci.h | 3 ++
drivers/cxl/pci.c | 58 ---------------------------------------
3 files changed, 65 insertions(+), 58 deletions(-)
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index a1942b7be0bc..bfc5e96e3cb9 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -1034,6 +1034,68 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
}
EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL);
+/*
+ * Assume that any RCIEP that emits the CXL memory expander class code
+ * is an RCD
+ */
+bool is_cxl_restricted(struct pci_dev *pdev)
+{
+ return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
+}
+EXPORT_SYMBOL_NS_GPL(is_cxl_restricted, CXL);
+
+static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
+ struct cxl_register_map *map)
+{
+ struct cxl_port *port;
+ struct cxl_dport *dport;
+ resource_size_t component_reg_phys;
+
+ *map = (struct cxl_register_map) {
+ .host = &pdev->dev,
+ .resource = CXL_RESOURCE_NONE,
+ };
+
+ port = cxl_pci_find_port(pdev, &dport);
+ if (!port)
+ return -EPROBE_DEFER;
+
+ component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
+
+ put_device(&port->dev);
+
+ if (component_reg_phys == CXL_RESOURCE_NONE)
+ return -ENXIO;
+
+ map->resource = component_reg_phys;
+ map->reg_type = CXL_REGLOC_RBI_COMPONENT;
+ map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
+
+ return 0;
+}
+
+int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
+ struct cxl_register_map *map, unsigned long *caps)
+{
+ int rc;
+
+ rc = cxl_find_regblock(pdev, type, map);
+
+ /*
+ * If the Register Locator DVSEC does not exist, check if it
+ * is an RCH and try to extract the Component Registers from
+ * an RCRB.
+ */
+ if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev))
+ rc = cxl_rcrb_get_comp_regs(pdev, map);
+
+ if (rc)
+ return rc;
+
+ return cxl_setup_regs(map, caps);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, CXL);
+
int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
{
int speed, bw;
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index eb59019fe5f3..985cca3c3350 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -113,4 +113,7 @@ void read_cdat_data(struct cxl_port *port);
void cxl_cor_error_detected(struct pci_dev *pdev);
pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
+bool is_cxl_restricted(struct pci_dev *pdev);
+int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
+ struct cxl_register_map *map, unsigned long *caps);
#endif /* __CXL_PCI_H__ */
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 5de1473a79da..caa7e101e063 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -467,64 +467,6 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail)
return 0;
}
-/*
- * Assume that any RCIEP that emits the CXL memory expander class code
- * is an RCD
- */
-static bool is_cxl_restricted(struct pci_dev *pdev)
-{
- return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
-}
-
-static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
- struct cxl_register_map *map)
-{
- struct cxl_dport *dport;
- resource_size_t component_reg_phys;
-
- *map = (struct cxl_register_map) {
- .host = &pdev->dev,
- .resource = CXL_RESOURCE_NONE,
- };
-
- struct cxl_port *port __free(put_cxl_port) =
- cxl_pci_find_port(pdev, &dport);
- if (!port)
- return -EPROBE_DEFER;
-
- component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
- if (component_reg_phys == CXL_RESOURCE_NONE)
- return -ENXIO;
-
- map->resource = component_reg_phys;
- map->reg_type = CXL_REGLOC_RBI_COMPONENT;
- map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
-
- return 0;
-}
-
-static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
- struct cxl_register_map *map,
- unsigned long *caps)
-{
- int rc;
-
- rc = cxl_find_regblock(pdev, type, map);
-
- /*
- * If the Register Locator DVSEC does not exist, check if it
- * is an RCH and try to extract the Component Registers from
- * an RCRB.
- */
- if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev))
- rc = cxl_rcrb_get_comp_regs(pdev, map);
-
- if (rc)
- return rc;
-
- return cxl_setup_regs(map, caps);
-}
-
static int cxl_pci_ras_unmask(struct pci_dev *pdev)
{
struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 06/27] cxl: add function for type2 cxl regs setup
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (4 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 05/27] cxl: move pci generic code alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 23:32 ` Dave Jiang
2024-11-21 22:34 ` Alison Schofield
2024-11-18 16:44 ` [PATCH v5 07/27] sfc: use cxl api for regs setup and checking alejandro.lucero-palau
` (21 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Create a new function for a type2 device initialising
cxl_dev_state struct regarding cxl regs setup and mapping.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/pci.c | 47 ++++++++++++++++++++++++++++++++++++++++++
include/cxl/cxl.h | 2 ++
2 files changed, 49 insertions(+)
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index bfc5e96e3cb9..8b9aa2c578e1 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -1096,6 +1096,53 @@ int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
}
EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, CXL);
+static int cxl_pci_setup_memdev_regs(struct pci_dev *pdev,
+ struct cxl_dev_state *cxlds)
+{
+ struct cxl_register_map map;
+ int rc;
+
+ rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
+ cxlds->capabilities);
+ /*
+ * This call returning a non-zero value is not considered an error since
+ * these regs are not mandatory for Type2. If they do exist then mapping
+ * them should not fail.
+ */
+ if (rc)
+ return 0;
+
+ return cxl_map_device_regs(&map, &cxlds->regs.device_regs);
+}
+
+int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds)
+{
+ int rc;
+
+ rc = cxl_pci_setup_memdev_regs(pdev, cxlds);
+ if (rc)
+ return rc;
+
+ rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
+ &cxlds->reg_map, cxlds->capabilities);
+ if (rc) {
+ dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
+ return rc;
+ }
+
+ if (!test_bit(CXL_CM_CAP_CAP_ID_RAS, cxlds->capabilities))
+ return rc;
+
+ rc = cxl_map_component_regs(&cxlds->reg_map,
+ &cxlds->regs.component,
+ BIT(CXL_CM_CAP_CAP_ID_RAS));
+ if (rc)
+ dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
+
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_pci_accel_setup_regs, CXL);
+
int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
{
int speed, bw;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index ab243ab8024f..a88d3475e551 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -5,6 +5,7 @@
#define __CXL_H
#include <linux/ioport.h>
+#include <linux/pci.h>
enum cxl_resource {
CXL_RES_DPA,
@@ -52,4 +53,5 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
unsigned long *expected_caps,
unsigned long *current_caps,
bool is_subset);
+int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 07/27] sfc: use cxl api for regs setup and checking
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (5 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 06/27] cxl: add function for type2 cxl regs setup alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 08/27] cxl: add functions for resource request/release by a driver alejandro.lucero-palau
` (20 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Use cxl code for registers discovery and mapping.
Validate capabilities found based on those registers against expected
capabilities.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 99f396028639..d6afd1b5499f 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -21,6 +21,8 @@
int efx_cxl_init(struct efx_probe_data *probe_data)
{
struct efx_nic *efx = &probe_data->efx;
+ DECLARE_BITMAP(expected, CXL_MAX_CAPS);
+ DECLARE_BITMAP(found, CXL_MAX_CAPS);
struct pci_dev *pci_dev;
struct efx_cxl *cxl;
struct resource res;
@@ -65,6 +67,23 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err2;
}
+ rc = cxl_pci_accel_setup_regs(pci_dev, cxl->cxlds);
+ if (rc) {
+ pci_err(pci_dev, "CXL accel setup regs failed");
+ goto err2;
+ }
+
+ bitmap_clear(expected, 0, CXL_MAX_CAPS);
+ bitmap_set(expected, CXL_DEV_CAP_HDM, 1);
+ bitmap_set(expected, CXL_DEV_CAP_RAS, 1);
+
+ if (!cxl_pci_check_caps(cxl->cxlds, expected, found, false)) {
+ pci_err(pci_dev,
+ "CXL device capabilities found(%08lx) not as expected(%08lx)",
+ *found, *expected);
+ goto err2;
+ }
+
probe_data->cxl = cxl;
return 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 08/27] cxl: add functions for resource request/release by a driver
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (6 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 07/27] sfc: use cxl api for regs setup and checking alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-22 20:45 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 09/27] sfc: request cxl ram resource alejandro.lucero-palau
` (19 subsequent siblings)
27 siblings, 1 reply; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Create accessors for an accel driver requesting and releasing a resource.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
include/cxl/cxl.h | 2 ++
2 files changed, 53 insertions(+)
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index d083fd13a6dd..7450172c1864 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -744,6 +744,57 @@ int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
}
EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
+int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
+{
+ int rc;
+
+ switch (type) {
+ case CXL_RES_RAM:
+ if (!resource_size(&cxlds->ram_res)) {
+ dev_err(cxlds->dev,
+ "resource request for ram with size 0\n");
+ return -EINVAL;
+ }
+
+ rc = request_resource(&cxlds->dpa_res, &cxlds->ram_res);
+ break;
+ case CXL_RES_PMEM:
+ if (!resource_size(&cxlds->pmem_res)) {
+ dev_err(cxlds->dev,
+ "resource request for pmem with size 0\n");
+ return -EINVAL;
+ }
+ rc = request_resource(&cxlds->dpa_res, &cxlds->pmem_res);
+ break;
+ default:
+ dev_err(cxlds->dev, "unsupported resource type (%u)\n", type);
+ return -EINVAL;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_request_resource, CXL);
+
+int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
+{
+ int rc;
+
+ switch (type) {
+ case CXL_RES_RAM:
+ rc = release_resource(&cxlds->ram_res);
+ break;
+ case CXL_RES_PMEM:
+ rc = release_resource(&cxlds->pmem_res);
+ break;
+ default:
+ dev_err(cxlds->dev, "unknown resource type (%u)\n", type);
+ return -EINVAL;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_release_resource, CXL);
+
static int cxl_memdev_release_file(struct inode *inode, struct file *file)
{
struct cxl_memdev *cxlmd =
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index a88d3475e551..e0bafd066b93 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -54,4 +54,6 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
unsigned long *current_caps,
bool is_subset);
int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
+int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
+int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 09/27] sfc: request cxl ram resource
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (7 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 08/27] cxl: add functions for resource request/release by a driver alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources alejandro.lucero-palau
` (18 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Use cxl accessor for obtaining the ram resource the device advertises.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index d6afd1b5499f..06a1cc752d55 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -84,6 +84,12 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err2;
}
+ rc = cxl_request_resource(cxl->cxlds, CXL_RES_RAM);
+ if (rc) {
+ pci_err(pci_dev, "CXL request resource failed");
+ goto err2;
+ }
+
probe_data->cxl = cxl;
return 0;
@@ -99,6 +105,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
void efx_cxl_exit(struct efx_probe_data *probe_data)
{
if (probe_data->cxl) {
+ cxl_release_resource(probe_data->cxl->cxlds, CXL_RES_RAM);
kfree(probe_data->cxl->cxlds);
kfree(probe_data->cxl);
}
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (8 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 09/27] sfc: request cxl ram resource alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 18:00 ` Dave Jiang
` (2 more replies)
2024-11-18 16:44 ` [PATCH v5 11/27] cxl: add function for setting media ready by a driver alejandro.lucero-palau
` (17 subsequent siblings)
27 siblings, 3 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
For a resource defined with size zero, resource_contains returns
always true.
Add resource size check before using it.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/hdm.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index 223c273c0cd1..c58d6b8f9b58 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
cxled->dpa_res = res;
cxled->skip = skipped;
- if (resource_contains(&cxlds->pmem_res, res))
+ if (resource_size(&cxlds->pmem_res) &&
+ resource_contains(&cxlds->pmem_res, res)) {
cxled->mode = CXL_DECODER_PMEM;
- else if (resource_contains(&cxlds->ram_res, res))
+ } else if (resource_size(&cxlds->ram_res) &&
+ resource_contains(&cxlds->ram_res, res)) {
cxled->mode = CXL_DECODER_RAM;
+ }
else {
dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
port->id, cxled->cxld.id, cxled->dpa_res);
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 11/27] cxl: add function for setting media ready by a driver
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (9 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 18:12 ` Dave Jiang
2024-11-22 20:45 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 12/27] sfc: set cxl media ready alejandro.lucero-palau
` (16 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
A Type-2 driver can require to set the memory availability explicitly.
Add a function to the exported CXL API for accelerator drivers.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/memdev.c | 6 ++++++
include/cxl/cxl.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 7450172c1864..d746c8a1021c 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -795,6 +795,12 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
}
EXPORT_SYMBOL_NS_GPL(cxl_release_resource, CXL);
+void cxl_set_media_ready(struct cxl_dev_state *cxlds)
+{
+ cxlds->media_ready = true;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_set_media_ready, CXL);
+
static int cxl_memdev_release_file(struct inode *inode, struct file *file)
{
struct cxl_memdev *cxlmd =
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index e0bafd066b93..6033ce84b3d3 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -56,4 +56,5 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
+void cxl_set_media_ready(struct cxl_dev_state *cxlds);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 12/27] sfc: set cxl media ready
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (10 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 11/27] cxl: add function for setting media ready by a driver alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 13/27] cxl: prepare memdev creation for type2 alejandro.lucero-palau
` (15 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Use cxl api accessor for explicitly set media ready as hardware design
implies it is ready and there is no device register for stating so.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 06a1cc752d55..9f862fc5ebfa 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -90,6 +90,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err2;
}
+ /* We do not have the register about media status. Hardware design
+ * implies it is ready.
+ */
+ cxl_set_media_ready(cxl->cxlds);
+
probe_data->cxl = cxl;
return 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (11 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 12/27] sfc: set cxl media ready alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 18:24 ` Dave Jiang
2024-11-22 20:45 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 14/27] sfc: create type2 cxl memdev alejandro.lucero-palau
` (14 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device when
creating a memdev leading to problems when obtaining cxl_memdev_state
references from a CXL_DEVTYPE_DEVMEM type. This last device type is
managed by a specific vendor driver and does not need same sysfs files
since not userspace intervention is expected.
Create a new cxl_mem device type with no attributes for Type2.
Avoid debugfs files relying on existence of clx_memdev_state.
Make devm_cxl_add_memdev accesible from a accel driver.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/cdat.c | 3 +++
drivers/cxl/core/memdev.c | 15 +++++++++++++--
drivers/cxl/core/region.c | 3 ++-
drivers/cxl/mem.c | 25 +++++++++++++++++++------
include/cxl/cxl.h | 2 ++
5 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
index e9cd7939c407..192cff18ea25 100644
--- a/drivers/cxl/core/cdat.c
+++ b/drivers/cxl/core/cdat.c
@@ -577,6 +577,9 @@ static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
struct cxl_dpa_perf *perf;
+ if (!mds)
+ return ERR_PTR(-EINVAL);
+
switch (mode) {
case CXL_DECODER_RAM:
perf = &mds->ram_perf;
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index d746c8a1021c..df31eea0c06b 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -547,9 +547,17 @@ static const struct device_type cxl_memdev_type = {
.groups = cxl_memdev_attribute_groups,
};
+static const struct device_type cxl_accel_memdev_type = {
+ .name = "cxl_memdev",
+ .release = cxl_memdev_release,
+ .devnode = cxl_memdev_devnode,
+};
+
bool is_cxl_memdev(const struct device *dev)
{
- return dev->type == &cxl_memdev_type;
+ return (dev->type == &cxl_memdev_type ||
+ dev->type == &cxl_accel_memdev_type);
+
}
EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
@@ -660,7 +668,10 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
dev->parent = cxlds->dev;
dev->bus = &cxl_bus_type;
dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
- dev->type = &cxl_memdev_type;
+ if (cxlds->type == CXL_DEVTYPE_DEVMEM)
+ dev->type = &cxl_accel_memdev_type;
+ else
+ dev->type = &cxl_memdev_type;
device_set_pm_not_required(dev);
INIT_WORK(&cxlmd->detach_work, detach_memdev);
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index dff618c708dc..622e3bb2e04b 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct cxl_region *cxlr,
return -EINVAL;
}
- cxl_region_perf_data_calculate(cxlr, cxled);
+ if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
+ cxl_region_perf_data_calculate(cxlr, cxled);
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
int i;
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index a9fd5cd5a0d2..cb771bf196cd 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
dentry = cxl_debugfs_create_dir(dev_name(dev));
debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
- if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
- debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
- &cxl_poison_inject_fops);
- if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
- debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
- &cxl_poison_clear_fops);
+ /*
+ * Avoid poison debugfs files for Type2 devices as they rely on
+ * cxl_memdev_state.
+ */
+ if (mds) {
+ if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
+ debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
+ &cxl_poison_inject_fops);
+ if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
+ debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
+ &cxl_poison_clear_fops);
+ }
rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
if (rc)
@@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
+ /*
+ * Avoid poison sysfs files for Type2 devices as they rely on
+ * cxl_memdev_state.
+ */
+ if (!mds)
+ return 0;
+
if (a == &dev_attr_trigger_poison_list.attr)
if (!test_bit(CXL_POISON_ENABLED_LIST,
mds->poison.enabled_cmds))
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 6033ce84b3d3..5608ed0f5f15 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
void cxl_set_media_ready(struct cxl_dev_state *cxlds);
+struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
+ struct cxl_dev_state *cxlds);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 14/27] sfc: create type2 cxl memdev
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (12 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 13/27] cxl: prepare memdev creation for type2 alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration alejandro.lucero-palau
` (13 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Use cxl API for creating a cxl memory device using the type2
cxl_dev_state struct.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 9f862fc5ebfa..7e900fbbc28e 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -95,10 +95,19 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
*/
cxl_set_media_ready(cxl->cxlds);
+ cxl->cxlmd = devm_cxl_add_memdev(&pci_dev->dev, cxl->cxlds);
+ if (IS_ERR(cxl->cxlmd)) {
+ pci_err(pci_dev, "CXL accel memdev creation failed");
+ rc = PTR_ERR(cxl->cxlmd);
+ goto err3;
+ }
+
probe_data->cxl = cxl;
return 0;
+err3:
+ cxl_release_resource(cxl->cxlds, CXL_RES_RAM);
err2:
kfree(cxl->cxlds);
err1:
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (13 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 14/27] sfc: create type2 cxl memdev alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-22 20:45 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 16/27] sfc: obtain root decoder with enough HPA free space alejandro.lucero-palau
` (12 subsequent siblings)
27 siblings, 1 reply; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
CXL region creation involves allocating capacity from device DPA
(device-physical-address space) and assigning it to decode a given HPA
(host-physical-address space). Before determining how much DPA to
allocate the amount of available HPA must be determined. Also, not all
HPA is create equal, some specifically targets RAM, some target PMEM,
some is prepared for device-memory flows like HDM-D and HDM-DB, and some
is host-only (HDM-H).
Wrap all of those concerns into an API that retrieves a root decoder
(platform CXL window) that fits the specified constraints and the
capacity available for a new region.
Based on https://lore.kernel.org/linux-cxl/168592159290.1948938.13522227102445462976.stgit@dwillia2-xfh.jf.intel.com/
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Co-developed-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/region.c | 141 ++++++++++++++++++++++++++++++++++++++
drivers/cxl/cxl.h | 3 +
include/cxl/cxl.h | 8 +++
3 files changed, 152 insertions(+)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 622e3bb2e04b..d107cc1b4350 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -687,6 +687,147 @@ static int free_hpa(struct cxl_region *cxlr)
return 0;
}
+struct cxlrd_max_context {
+ struct device *host_bridge;
+ unsigned long flags;
+ resource_size_t max_hpa;
+ struct cxl_root_decoder *cxlrd;
+};
+
+static int find_max_hpa(struct device *dev, void *data)
+{
+ struct cxlrd_max_context *ctx = data;
+ struct cxl_switch_decoder *cxlsd;
+ struct cxl_root_decoder *cxlrd;
+ struct resource *res, *prev;
+ struct cxl_decoder *cxld;
+ resource_size_t max;
+
+ if (!is_root_decoder(dev))
+ return 0;
+
+ cxlrd = to_cxl_root_decoder(dev);
+ cxlsd = &cxlrd->cxlsd;
+ cxld = &cxlsd->cxld;
+ if ((cxld->flags & ctx->flags) != ctx->flags) {
+ dev_dbg(dev, "%s, flags not matching: %08lx vs %08lx\n",
+ __func__, cxld->flags, ctx->flags);
+ return 0;
+ }
+
+ /* An accelerator can not be part of an interleaved HPA range. */
+ if (cxld->interleave_ways != 1) {
+ dev_dbg(dev, "%s, interleave_ways not matching\n", __func__);
+ return 0;
+ }
+
+ guard(rwsem_read)(&cxl_region_rwsem);
+ if (ctx->host_bridge != cxlsd->target[0]->dport_dev) {
+ dev_dbg(dev, "%s, host bridge does not match\n", __func__);
+ return 0;
+ }
+
+ /*
+ * Walk the root decoder resource range relying on cxl_region_rwsem to
+ * preclude sibling arrival/departure and find the largest free space
+ * gap.
+ */
+ lockdep_assert_held_read(&cxl_region_rwsem);
+ max = 0;
+ res = cxlrd->res->child;
+ if (!res)
+ max = resource_size(cxlrd->res);
+ else
+ max = 0;
+
+ for (prev = NULL; res; prev = res, res = res->sibling) {
+ struct resource *next = res->sibling;
+ resource_size_t free = 0;
+
+ if (!prev && res->start > cxlrd->res->start) {
+ free = res->start - cxlrd->res->start;
+ max = max(free, max);
+ }
+ if (prev && res->start > prev->end + 1) {
+ free = res->start - prev->end + 1;
+ max = max(free, max);
+ }
+ if (next && res->end + 1 < next->start) {
+ free = next->start - res->end + 1;
+ max = max(free, max);
+ }
+ if (!next && res->end + 1 < cxlrd->res->end + 1) {
+ free = cxlrd->res->end + 1 - res->end + 1;
+ max = max(free, max);
+ }
+ }
+
+ dev_dbg(CXLRD_DEV(cxlrd), "%s, found %pa bytes of free space\n",
+ __func__, &max);
+ if (max > ctx->max_hpa) {
+ if (ctx->cxlrd)
+ put_device(CXLRD_DEV(ctx->cxlrd));
+ get_device(CXLRD_DEV(cxlrd));
+ ctx->cxlrd = cxlrd;
+ ctx->max_hpa = max;
+ dev_dbg(CXLRD_DEV(cxlrd), "%s, found %pa bytes of free space\n",
+ __func__, &max);
+ }
+ return 0;
+}
+
+/**
+ * cxl_get_hpa_freespace - find a root decoder with free capacity per constraints
+ * @endpoint: an endpoint that is mapped by the returned decoder
+ * @flags: CXL_DECODER_F flags for selecting RAM vs PMEM, and HDM-H vs HDM-D[B]
+ * @max_avail_contig: output parameter of max contiguous bytes available in the
+ * returned decoder
+ *
+ * The return tuple of a 'struct cxl_root_decoder' and 'bytes available (@max)'
+ * is a point in time snapshot. If by the time the caller goes to use this root
+ * decoder's capacity the capacity is reduced then caller needs to loop and
+ * retry.
+ *
+ * The returned root decoder has an elevated reference count that needs to be
+ * put with put_device(cxlrd_dev(cxlrd)). Locking context is with
+ * cxl_{acquire,release}_endpoint(), that ensures removal of the root decoder
+ * does not race.
+ */
+struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
+ unsigned long flags,
+ resource_size_t *max_avail_contig)
+{
+ struct cxl_port *endpoint = cxlmd->endpoint;
+ struct cxlrd_max_context ctx = {
+ .host_bridge = endpoint->host_bridge,
+ .flags = flags,
+ };
+ struct cxl_port *root_port;
+ struct cxl_root *root __free(put_cxl_root) = find_cxl_root(endpoint);
+
+ if (!is_cxl_endpoint(endpoint)) {
+ dev_dbg(&endpoint->dev, "hpa requestor is not an endpoint\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!root) {
+ dev_dbg(&endpoint->dev, "endpoint can not be related to a root port\n");
+ return ERR_PTR(-ENXIO);
+ }
+
+ root_port = &root->port;
+ down_read(&cxl_region_rwsem);
+ device_for_each_child(&root_port->dev, &ctx, find_max_hpa);
+ up_read(&cxl_region_rwsem);
+
+ if (!ctx.cxlrd)
+ return ERR_PTR(-ENOMEM);
+
+ *max_avail_contig = ctx.max_hpa;
+ return ctx.cxlrd;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_get_hpa_freespace, CXL);
+
static ssize_t size_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index e5f918be6fe4..1e0e797b9303 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -776,6 +776,9 @@ static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport,
struct cxl_decoder *to_cxl_decoder(struct device *dev);
struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev);
+
+#define CXLRD_DEV(cxlrd) (&(cxlrd)->cxlsd.cxld.dev)
+
struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
bool is_root_decoder(struct device *dev);
bool is_switch_decoder(struct device *dev);
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 5608ed0f5f15..4508b5c186e8 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -7,6 +7,10 @@
#include <linux/ioport.h>
#include <linux/pci.h>
+#define CXL_DECODER_F_RAM BIT(0)
+#define CXL_DECODER_F_PMEM BIT(1)
+#define CXL_DECODER_F_TYPE2 BIT(2)
+
enum cxl_resource {
CXL_RES_DPA,
CXL_RES_RAM,
@@ -59,4 +63,8 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
void cxl_set_media_ready(struct cxl_dev_state *cxlds);
struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
struct cxl_dev_state *cxlds);
+struct cxl_port;
+struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
+ unsigned long flags,
+ resource_size_t *max);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 16/27] sfc: obtain root decoder with enough HPA free space
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (14 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 17/27] cxl: define a driver interface for DPA allocation alejandro.lucero-palau
` (11 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Asking for availbale HPA space is the previous step to try to obtain
an HPA range suitable to accel driver purposes.
Add this call to efx cxl initialization.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 7e900fbbc28e..048500492371 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -26,6 +26,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
struct pci_dev *pci_dev;
struct efx_cxl *cxl;
struct resource res;
+ resource_size_t max;
u16 dvsec;
int rc;
@@ -102,6 +103,23 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err3;
}
+ cxl->cxlrd = cxl_get_hpa_freespace(cxl->cxlmd,
+ CXL_DECODER_F_RAM | CXL_DECODER_F_TYPE2,
+ &max);
+
+ if (IS_ERR(cxl->cxlrd)) {
+ pci_err(pci_dev, "cxl_get_hpa_freespace failed\n");
+ rc = PTR_ERR(cxl->cxlrd);
+ goto err3;
+ }
+
+ if (max < EFX_CTPIO_BUFFER_SIZE) {
+ pci_err(pci_dev, "%s: no enough free HPA space %llu < %u\n",
+ __func__, max, EFX_CTPIO_BUFFER_SIZE);
+ rc = -ENOSPC;
+ goto err3;
+ }
+
probe_data->cxl = cxl;
return 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 17/27] cxl: define a driver interface for DPA allocation
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (15 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 16/27] sfc: obtain root decoder with enough HPA free space alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 18/27] sfc: get endpoint decoder alejandro.lucero-palau
` (10 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Region creation involves finding available DPA (device-physical-address)
capacity to map into HPA (host-physical-address) space. Given the HPA
capacity constraint, define an API, cxl_request_dpa(), that has the
flexibility to map the minimum amount of memory the driver needs to
operate vs the total possible that can be mapped given HPA availability.
Factor out the core of cxl_dpa_alloc, that does free space scanning,
into a cxl_dpa_freespace() helper, and use that to balance the capacity
available to map vs the @min and @max arguments to cxl_request_dpa.
Based on https://lore.kernel.org/linux-cxl/168592158743.1948938.7622563891193802610.stgit@dwillia2-xfh.jf.intel.com/
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Co-developed-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/hdm.c | 153 +++++++++++++++++++++++++++++++++++------
include/cxl/cxl.h | 5 ++
2 files changed, 138 insertions(+), 20 deletions(-)
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index c58d6b8f9b58..99c32f1a0c97 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -3,6 +3,7 @@
#include <linux/seq_file.h>
#include <linux/device.h>
#include <linux/delay.h>
+#include <cxl/cxl.h>
#include "cxlmem.h"
#include "core.h"
@@ -420,6 +421,7 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
up_write(&cxl_dpa_rwsem);
return rc;
}
+EXPORT_SYMBOL_NS_GPL(cxl_dpa_free, CXL);
int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
enum cxl_decoder_mode mode)
@@ -467,31 +469,18 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
return rc;
}
-int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
+static resource_size_t cxl_dpa_freespace(struct cxl_endpoint_decoder *cxled,
+ resource_size_t *start_out,
+ resource_size_t *skip_out)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
resource_size_t free_ram_start, free_pmem_start;
- struct cxl_port *port = cxled_to_port(cxled);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
- struct device *dev = &cxled->cxld.dev;
resource_size_t start, avail, skip;
struct resource *p, *last;
- int rc;
-
- down_write(&cxl_dpa_rwsem);
- if (cxled->cxld.region) {
- dev_dbg(dev, "decoder attached to %s\n",
- dev_name(&cxled->cxld.region->dev));
- rc = -EBUSY;
- goto out;
- }
- if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
- dev_dbg(dev, "decoder enabled\n");
- rc = -EBUSY;
- goto out;
- }
+ lockdep_assert_held(&cxl_dpa_rwsem);
for (p = cxlds->ram_res.child, last = NULL; p; p = p->sibling)
last = p;
if (last)
@@ -528,14 +517,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
skip_end = start - 1;
skip = skip_end - skip_start + 1;
} else {
- dev_dbg(dev, "mode not set\n");
- rc = -EINVAL;
+ avail = 0;
+ }
+
+ if (!avail)
+ return 0;
+ if (start_out)
+ *start_out = start;
+ if (skip_out)
+ *skip_out = skip;
+ return avail;
+}
+
+int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
+{
+ struct cxl_port *port = cxled_to_port(cxled);
+ struct device *dev = &cxled->cxld.dev;
+ resource_size_t start, avail, skip;
+ int rc;
+
+ down_write(&cxl_dpa_rwsem);
+ if (cxled->cxld.region) {
+ dev_dbg(dev, "EBUSY, decoder attached to %s\n",
+ dev_name(&cxled->cxld.region->dev));
+ rc = -EBUSY;
goto out;
}
+ if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
+ dev_dbg(dev, "EBUSY, decoder enabled\n");
+ rc = -EBUSY;
+ goto out;
+ }
+
+ avail = cxl_dpa_freespace(cxled, &start, &skip);
+
if (size > avail) {
dev_dbg(dev, "%pa exceeds available %s capacity: %pa\n", &size,
- cxl_decoder_mode_name(cxled->mode), &avail);
+ cxled->mode == CXL_DECODER_RAM ? "ram" : "pmem",
+ &avail);
rc = -ENOSPC;
goto out;
}
@@ -550,6 +570,99 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
}
+static int find_free_decoder(struct device *dev, void *data)
+{
+ struct cxl_endpoint_decoder *cxled;
+ struct cxl_port *port;
+
+ if (!is_endpoint_decoder(dev))
+ return 0;
+
+ cxled = to_cxl_endpoint_decoder(dev);
+ port = cxled_to_port(cxled);
+
+ if (cxled->cxld.id != port->hdm_end + 1)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * cxl_request_dpa - search and reserve DPA given input constraints
+ * @endpoint: an endpoint port with available decoders
+ * @is_ram: DPA operation mode (ram vs pmem)
+ * @min: the minimum amount of capacity the call needs
+ * @max: extra capacity to allocate after min is satisfied
+ *
+ * Given that a region needs to allocate from limited HPA capacity it
+ * may be the case that a device has more mappable DPA capacity than
+ * available HPA. So, the expectation is that @min is a driver known
+ * value for how much capacity is needed, and @max is based the limit of
+ * how much HPA space is available for a new region.
+ *
+ * Returns a pinned cxl_decoder with at least @min bytes of capacity
+ * reserved, or an error pointer. The caller is also expected to own the
+ * lifetime of the memdev registration associated with the endpoint to
+ * pin the decoder registered as well.
+ */
+struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
+ bool is_ram,
+ resource_size_t min,
+ resource_size_t max)
+{
+ struct cxl_port *endpoint = cxlmd->endpoint;
+ struct cxl_endpoint_decoder *cxled;
+ enum cxl_decoder_mode mode;
+ struct device *cxled_dev;
+ resource_size_t alloc;
+ int rc;
+
+ if (!IS_ALIGNED(min | max, SZ_256M))
+ return ERR_PTR(-EINVAL);
+
+ down_read(&cxl_dpa_rwsem);
+ cxled_dev = device_find_child(&endpoint->dev, NULL, find_free_decoder);
+ up_read(&cxl_dpa_rwsem);
+
+ if (!cxled_dev)
+ cxled = ERR_PTR(-ENXIO);
+ else
+ cxled = to_cxl_endpoint_decoder(cxled_dev);
+
+ if (!cxled || IS_ERR(cxled))
+ return cxled;
+
+ if (is_ram)
+ mode = CXL_DECODER_RAM;
+ else
+ mode = CXL_DECODER_PMEM;
+
+ rc = cxl_dpa_set_mode(cxled, mode);
+ if (rc)
+ goto err;
+
+ down_read(&cxl_dpa_rwsem);
+ alloc = cxl_dpa_freespace(cxled, NULL, NULL);
+ up_read(&cxl_dpa_rwsem);
+
+ if (max)
+ alloc = min(max, alloc);
+ if (alloc < min) {
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ rc = cxl_dpa_alloc(cxled, alloc);
+ if (rc)
+ goto err;
+
+ return cxled;
+err:
+ put_device(cxled_dev);
+ return ERR_PTR(rc);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_request_dpa, CXL);
+
static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
{
u16 eig;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 4508b5c186e8..9b5b5472a86b 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -67,4 +67,9 @@ struct cxl_port;
struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
unsigned long flags,
resource_size_t *max);
+struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
+ bool is_ram,
+ resource_size_t min,
+ resource_size_t max);
+int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 18/27] sfc: get endpoint decoder
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (16 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 17/27] cxl: define a driver interface for DPA allocation alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-22 20:45 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 19/27] cxl: make region type based on endpoint type alejandro.lucero-palau
` (9 subsequent siblings)
27 siblings, 1 reply; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Use cxl api for getting DPA (Device Physical Address) to use through an
endpoint decoder.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 048500492371..85d9632f497a 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -120,6 +120,14 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err3;
}
+ cxl->cxled = cxl_request_dpa(cxl->cxlmd, true, EFX_CTPIO_BUFFER_SIZE,
+ EFX_CTPIO_BUFFER_SIZE);
+ if (!cxl->cxled || IS_ERR(cxl->cxled)) {
+ pci_err(pci_dev, "CXL accel request DPA failed");
+ rc = PTR_ERR(cxl->cxlrd);
+ goto err3;
+ }
+
probe_data->cxl = cxl;
return 0;
@@ -137,6 +145,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
void efx_cxl_exit(struct efx_probe_data *probe_data)
{
if (probe_data->cxl) {
+ cxl_dpa_free(probe_data->cxl->cxled);
cxl_release_resource(probe_data->cxl->cxlds, CXL_RES_RAM);
kfree(probe_data->cxl->cxlds);
kfree(probe_data->cxl);
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 19/27] cxl: make region type based on endpoint type
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (17 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 18/27] sfc: get endpoint decoder alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 20:16 ` Zhi Wang
2024-11-21 16:16 ` Dave Jiang
2024-11-18 16:44 ` [PATCH v5 20/27] cxl/region: factor out interleave ways setup alejandro.lucero-palau
` (8 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Current code is expecting Type3 or CXL_DECODER_HOSTONLYMEM devices only.
Support for Type2 implies region type needs to be based on the endpoint
type instead.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/region.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index d107cc1b4350..8e2dbd15cfc0 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2654,7 +2654,8 @@ static ssize_t create_ram_region_show(struct device *dev,
}
static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
- enum cxl_decoder_mode mode, int id)
+ enum cxl_decoder_mode mode, int id,
+ enum cxl_decoder_type target_type)
{
int rc;
@@ -2676,7 +2677,7 @@ static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
return ERR_PTR(-EBUSY);
}
- return devm_cxl_add_region(cxlrd, id, mode, CXL_DECODER_HOSTONLYMEM);
+ return devm_cxl_add_region(cxlrd, id, mode, target_type);
}
static ssize_t create_pmem_region_store(struct device *dev,
@@ -2691,7 +2692,8 @@ static ssize_t create_pmem_region_store(struct device *dev,
if (rc != 1)
return -EINVAL;
- cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id);
+ cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id,
+ CXL_DECODER_HOSTONLYMEM);
if (IS_ERR(cxlr))
return PTR_ERR(cxlr);
@@ -2711,7 +2713,8 @@ static ssize_t create_ram_region_store(struct device *dev,
if (rc != 1)
return -EINVAL;
- cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id);
+ cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id,
+ CXL_DECODER_HOSTONLYMEM);
if (IS_ERR(cxlr))
return PTR_ERR(cxlr);
@@ -3372,7 +3375,8 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
do {
cxlr = __create_region(cxlrd, cxled->mode,
- atomic_read(&cxlrd->region_id));
+ atomic_read(&cxlrd->region_id),
+ cxled->cxld.target_type);
} while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
if (IS_ERR(cxlr)) {
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 20/27] cxl/region: factor out interleave ways setup
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (18 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 19/27] cxl: make region type based on endpoint type alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 20:20 ` Zhi Wang
2024-11-21 16:23 ` Dave Jiang
2024-11-18 16:44 ` [PATCH v5 21/27] cxl/region: factor out interleave granularity setup alejandro.lucero-palau
` (7 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
In preparation for kernel driven region creation, factor out a common
helper from the user-sysfs region setup for interleave ways.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Co-developed-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/region.c | 46 +++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 8e2dbd15cfc0..04f82adb763f 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -464,22 +464,14 @@ static ssize_t interleave_ways_show(struct device *dev,
static const struct attribute_group *get_cxl_region_target_group(void);
-static ssize_t interleave_ways_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+static int set_interleave_ways(struct cxl_region *cxlr, int val)
{
- struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent);
+ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
- struct cxl_region *cxlr = to_cxl_region(dev);
struct cxl_region_params *p = &cxlr->params;
- unsigned int val, save;
- int rc;
+ int save, rc;
u8 iw;
- rc = kstrtouint(buf, 0, &val);
- if (rc)
- return rc;
-
rc = ways_to_eiw(val, &iw);
if (rc)
return rc;
@@ -494,20 +486,36 @@ static ssize_t interleave_ways_store(struct device *dev,
return -EINVAL;
}
- rc = down_write_killable(&cxl_region_rwsem);
- if (rc)
- return rc;
- if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
- rc = -EBUSY;
- goto out;
- }
+ lockdep_assert_held_write(&cxl_region_rwsem);
+ if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
+ return -EBUSY;
save = p->interleave_ways;
p->interleave_ways = val;
rc = sysfs_update_group(&cxlr->dev.kobj, get_cxl_region_target_group());
if (rc)
p->interleave_ways = save;
-out:
+
+ return rc;
+}
+
+static ssize_t interleave_ways_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct cxl_region *cxlr = to_cxl_region(dev);
+ unsigned int val;
+ int rc;
+
+ rc = kstrtouint(buf, 0, &val);
+ if (rc)
+ return rc;
+
+ rc = down_write_killable(&cxl_region_rwsem);
+ if (rc)
+ return rc;
+
+ rc = set_interleave_ways(cxlr, val);
up_write(&cxl_region_rwsem);
if (rc)
return rc;
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 21/27] cxl/region: factor out interleave granularity setup
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (19 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 20/27] cxl/region: factor out interleave ways setup alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 20:23 ` Zhi Wang
2024-11-21 16:24 ` Dave Jiang
2024-11-18 16:44 ` [PATCH v5 22/27] cxl: allow region creation by type2 drivers alejandro.lucero-palau
` (6 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
In preparation for kernel driven region creation, factor out a common
helper from the user-sysfs region setup for interleave granularity.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Co-developed-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/region.c | 39 +++++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 04f82adb763f..6652887ea396 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -540,21 +540,14 @@ static ssize_t interleave_granularity_show(struct device *dev,
return rc;
}
-static ssize_t interleave_granularity_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+static int set_interleave_granularity(struct cxl_region *cxlr, int val)
{
- struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent);
+ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
- struct cxl_region *cxlr = to_cxl_region(dev);
struct cxl_region_params *p = &cxlr->params;
- int rc, val;
+ int rc;
u16 ig;
- rc = kstrtoint(buf, 0, &val);
- if (rc)
- return rc;
-
rc = granularity_to_eig(val, &ig);
if (rc)
return rc;
@@ -570,16 +563,30 @@ static ssize_t interleave_granularity_store(struct device *dev,
if (cxld->interleave_ways > 1 && val != cxld->interleave_granularity)
return -EINVAL;
+ lockdep_assert_held_write(&cxl_region_rwsem);
+ if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
+ return -EBUSY;
+
+ p->interleave_granularity = val;
+ return 0;
+}
+
+static ssize_t interleave_granularity_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct cxl_region *cxlr = to_cxl_region(dev);
+ int rc, val;
+
+ rc = kstrtoint(buf, 0, &val);
+ if (rc)
+ return rc;
+
rc = down_write_killable(&cxl_region_rwsem);
if (rc)
return rc;
- if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
- rc = -EBUSY;
- goto out;
- }
- p->interleave_granularity = val;
-out:
+ rc = set_interleave_granularity(cxlr, val);
up_write(&cxl_region_rwsem);
if (rc)
return rc;
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 22/27] cxl: allow region creation by type2 drivers
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (20 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 21/27] cxl/region: factor out interleave granularity setup alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 20:37 ` Zhi Wang
2024-11-18 16:44 ` [PATCH v5 23/27] sfc: create cxl region alejandro.lucero-palau
` (5 subsequent siblings)
27 siblings, 1 reply; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Creating a CXL region requires userspace intervention through the cxl
sysfs files. Type2 support should allow accelerator drivers to create
such cxl region from kernel code.
Adding that functionality and integrating it with current support for
memory expanders.
Based on https://lore.kernel.org/linux-cxl/168592159835.1948938.1647215579839222774.stgit@dwillia2-xfh.jf.intel.com/
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/region.c | 147 ++++++++++++++++++++++++++++++++++----
drivers/cxl/cxlmem.h | 2 +
drivers/cxl/port.c | 5 +-
include/cxl/cxl.h | 4 ++
4 files changed, 142 insertions(+), 16 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 6652887ea396..70549d42c2e3 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2256,6 +2256,18 @@ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled)
return rc;
}
+int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled)
+{
+ int rc;
+
+ down_write(&cxl_region_rwsem);
+ cxled->mode = CXL_DECODER_DEAD;
+ rc = cxl_region_detach(cxled);
+ up_write(&cxl_region_rwsem);
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_accel_region_detach, CXL);
+
void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
{
down_write(&cxl_region_rwsem);
@@ -2770,6 +2782,14 @@ cxl_find_region_by_name(struct cxl_root_decoder *cxlrd, const char *name)
return to_cxl_region(region_dev);
}
+static void drop_region(struct cxl_region *cxlr)
+{
+ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
+ struct cxl_port *port = cxlrd_to_port(cxlrd);
+
+ devm_release_action(port->uport_dev, unregister_region, cxlr);
+}
+
static ssize_t delete_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
@@ -3376,17 +3396,18 @@ static int match_region_by_range(struct device *dev, void *data)
return rc;
}
-/* Establish an empty region covering the given HPA range */
-static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
- struct cxl_endpoint_decoder *cxled)
+static void construct_region_end(void)
+{
+ up_write(&cxl_region_rwsem);
+}
+
+static struct cxl_region *construct_region_begin(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
- struct cxl_port *port = cxlrd_to_port(cxlrd);
- struct range *hpa = &cxled->cxld.hpa_range;
struct cxl_region_params *p;
struct cxl_region *cxlr;
- struct resource *res;
- int rc;
+ int err;
do {
cxlr = __create_region(cxlrd, cxled->mode,
@@ -3395,8 +3416,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
} while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
if (IS_ERR(cxlr)) {
- dev_err(cxlmd->dev.parent,
- "%s:%s: %s failed assign region: %ld\n",
+ dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n",
dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
__func__, PTR_ERR(cxlr));
return cxlr;
@@ -3406,13 +3426,33 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
p = &cxlr->params;
if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
dev_err(cxlmd->dev.parent,
- "%s:%s: %s autodiscovery interrupted\n",
+ "%s:%s: %s region setup interrupted\n",
dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
__func__);
- rc = -EBUSY;
- goto err;
+ err = -EBUSY;
+ construct_region_end();
+ drop_region(cxlr);
+ return ERR_PTR(err);
}
+ return cxlr;
+}
+
+/* Establish an empty region covering the given HPA range */
+static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled)
+{
+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+ struct range *hpa = &cxled->cxld.hpa_range;
+ struct cxl_region_params *p;
+ struct cxl_region *cxlr;
+ struct resource *res;
+ int rc;
+
+ cxlr = construct_region_begin(cxlrd, cxled);
+ if (IS_ERR(cxlr))
+ return cxlr;
+
set_bit(CXL_REGION_F_AUTO, &cxlr->flags);
res = kmalloc(sizeof(*res), GFP_KERNEL);
@@ -3435,6 +3475,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
__func__, dev_name(&cxlr->dev));
}
+ p = &cxlr->params;
p->res = res;
p->interleave_ways = cxled->cxld.interleave_ways;
p->interleave_granularity = cxled->cxld.interleave_granularity;
@@ -3452,15 +3493,91 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
/* ...to match put_device() in cxl_add_to_region() */
get_device(&cxlr->dev);
up_write(&cxl_region_rwsem);
-
+ construct_region_end();
return cxlr;
err:
- up_write(&cxl_region_rwsem);
- devm_release_action(port->uport_dev, unregister_region, cxlr);
+ construct_region_end();
+ drop_region(cxlr);
+ return ERR_PTR(rc);
+}
+
+static struct cxl_region *
+__construct_new_region(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled)
+{
+ struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
+ struct cxl_region_params *p;
+ struct cxl_region *cxlr;
+ int rc;
+
+ cxlr = construct_region_begin(cxlrd, cxled);
+ if (IS_ERR(cxlr))
+ return cxlr;
+
+ rc = set_interleave_ways(cxlr, 1);
+ if (rc)
+ goto err;
+
+ rc = set_interleave_granularity(cxlr, cxld->interleave_granularity);
+ if (rc)
+ goto err;
+
+ rc = alloc_hpa(cxlr, resource_size(cxled->dpa_res));
+ if (rc)
+ goto err;
+
+ down_read(&cxl_dpa_rwsem);
+ rc = cxl_region_attach(cxlr, cxled, 0);
+ up_read(&cxl_dpa_rwsem);
+
+ if (rc)
+ goto err;
+
+ rc = cxl_region_decode_commit(cxlr);
+ if (rc)
+ goto err;
+
+ p = &cxlr->params;
+ p->state = CXL_CONFIG_COMMIT;
+
+ construct_region_end();
+ return cxlr;
+err:
+ construct_region_end();
+ drop_region(cxlr);
return ERR_PTR(rc);
}
+/**
+ * cxl_create_region - Establish a region given an endpoint decoder
+ * @cxlrd: root decoder to allocate HPA
+ * @cxled: endpoint decoder with reserved DPA capacity
+ *
+ * Returns a fully formed region in the commit state and attached to the
+ * cxl_region driver.
+ */
+struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled)
+{
+ struct cxl_region *cxlr;
+
+ mutex_lock(&cxlrd->range_lock);
+ cxlr = __construct_new_region(cxlrd, cxled);
+ mutex_unlock(&cxlrd->range_lock);
+
+ if (IS_ERR(cxlr))
+ return cxlr;
+
+ if (device_attach(&cxlr->dev) <= 0) {
+ dev_err(&cxlr->dev, "failed to create region\n");
+ drop_region(cxlr);
+ return ERR_PTR(-ENODEV);
+ }
+ return cxlr;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
+
int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 4c1c53c29544..9d874f1cb3bf 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -874,4 +874,6 @@ struct cxl_hdm {
struct seq_file;
struct dentry *cxl_debugfs_create_dir(const char *dir);
void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
+struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled);
#endif /* __CXL_MEM_H__ */
diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c
index acf2ac70f343..ec1f0cfb11a5 100644
--- a/drivers/cxl/port.c
+++ b/drivers/cxl/port.c
@@ -33,6 +33,7 @@ static void schedule_detach(void *cxlmd)
static int discover_region(struct device *dev, void *root)
{
struct cxl_endpoint_decoder *cxled;
+ struct cxl_memdev *cxlmd;
int rc;
if (!is_endpoint_decoder(dev))
@@ -42,7 +43,9 @@ static int discover_region(struct device *dev, void *root)
if ((cxled->cxld.flags & CXL_DECODER_F_ENABLE) == 0)
return 0;
- if (cxled->state != CXL_DECODER_STATE_AUTO)
+ cxlmd = cxled_to_memdev(cxled);
+ if (cxled->state != CXL_DECODER_STATE_AUTO ||
+ cxlmd->cxlds->type == CXL_DEVTYPE_DEVMEM)
return 0;
/*
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 9b5b5472a86b..d295af4f5f9e 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -72,4 +72,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
resource_size_t min,
resource_size_t max);
int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
+struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled);
+
+int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 23/27] sfc: create cxl region
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (21 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 22/27] cxl: allow region creation by type2 drivers alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax alejandro.lucero-palau
` (4 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Use cxl api for creating a region using the endpoint decoder related to
a DPA range.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 85d9632f497a..f9f3af28690b 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -128,10 +128,19 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err3;
}
+ cxl->efx_region = cxl_create_region(cxl->cxlrd, cxl->cxled);
+ if (!cxl->efx_region) {
+ pci_err(pci_dev, "CXL accel create region failed");
+ rc = PTR_ERR(cxl->efx_region);
+ goto err_region;
+ }
+
probe_data->cxl = cxl;
return 0;
+err_region:
+ cxl_dpa_free(cxl->cxled);
err3:
cxl_release_resource(cxl->cxlds, CXL_RES_RAM);
err2:
@@ -145,6 +154,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
void efx_cxl_exit(struct efx_probe_data *probe_data)
{
if (probe_data->cxl) {
+ cxl_accel_region_detach(probe_data->cxl->cxled);
cxl_dpa_free(probe_data->cxl->cxled);
cxl_release_resource(probe_data->cxl->cxlds, CXL_RES_RAM);
kfree(probe_data->cxl->cxlds);
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (22 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 23/27] sfc: create cxl region alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 20:39 ` Zhi Wang
2024-11-22 20:46 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 25/27] sfc: specify avoid dax when cxl region is created alejandro.lucero-palau
` (3 subsequent siblings)
27 siblings, 2 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
By definition a type2 cxl device will use the host managed memory for
specific functionality, therefore it should not be available to other
uses. However, a dax interface could be just good enough in some cases.
Add a flag to a cxl region for specifically state to not create a dax
device. Allow a Type2 driver to set that flag at region creation time.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/region.c | 10 +++++++++-
drivers/cxl/cxl.h | 3 +++
drivers/cxl/cxlmem.h | 3 ++-
include/cxl/cxl.h | 3 ++-
4 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 70549d42c2e3..eff3ad788077 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -3558,7 +3558,8 @@ __construct_new_region(struct cxl_root_decoder *cxlrd,
* cxl_region driver.
*/
struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
- struct cxl_endpoint_decoder *cxled)
+ struct cxl_endpoint_decoder *cxled,
+ bool avoid_dax)
{
struct cxl_region *cxlr;
@@ -3574,6 +3575,10 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
drop_region(cxlr);
return ERR_PTR(-ENODEV);
}
+
+ if (avoid_dax)
+ set_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags);
+
return cxlr;
}
EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
@@ -3713,6 +3718,9 @@ static int cxl_region_probe(struct device *dev)
case CXL_DECODER_PMEM:
return devm_cxl_add_pmem_region(cxlr);
case CXL_DECODER_RAM:
+ if (test_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags))
+ return 0;
+
/*
* The region can not be manged by CXL if any portion of
* it is already online as 'System RAM'
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 1e0e797b9303..ee3385db5663 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -512,6 +512,9 @@ struct cxl_region_params {
*/
#define CXL_REGION_F_NEEDS_RESET 1
+/* Allow Type2 drivers to specify if a dax region should not be created. */
+#define CXL_REGION_F_AVOID_DAX 2
+
/**
* struct cxl_region - CXL region
* @dev: This region's device
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 9d874f1cb3bf..cc2e2a295f3d 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -875,5 +875,6 @@ struct seq_file;
struct dentry *cxl_debugfs_create_dir(const char *dir);
void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
- struct cxl_endpoint_decoder *cxled);
+ struct cxl_endpoint_decoder *cxled,
+ bool avoid_dax);
#endif /* __CXL_MEM_H__ */
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index d295af4f5f9e..2a8ebabfc1dd 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -73,7 +73,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
resource_size_t max);
int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
- struct cxl_endpoint_decoder *cxled);
+ struct cxl_endpoint_decoder *cxled,
+ bool avoid_dax);
int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 25/27] sfc: specify avoid dax when cxl region is created
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (23 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 26/27] cxl: add function for obtaining params from a region alejandro.lucero-palau
` (2 subsequent siblings)
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
The CXL memory should not be used by the host in any case except for
what the driver allows. Tell the cxl core to not create a DAX device
using the avoid dax at region creation time.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index f9f3af28690b..de8d6bca9300 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -128,7 +128,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err3;
}
- cxl->efx_region = cxl_create_region(cxl->cxlrd, cxl->cxled);
+ cxl->efx_region = cxl_create_region(cxl->cxlrd, cxl->cxled, true);
if (!cxl->efx_region) {
pci_err(pci_dev, "CXL accel create region failed");
rc = PTR_ERR(cxl->efx_region);
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 26/27] cxl: add function for obtaining params from a region
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (24 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 25/27] sfc: specify avoid dax when cxl region is created alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-19 20:40 ` Zhi Wang
` (2 more replies)
2024-11-18 16:44 ` [PATCH v5 27/27] sfc: support pio mapping based on cxl alejandro.lucero-palau
2024-11-21 3:33 ` [PATCH v5 00/27] cxl: add type2 device basic support Alison Schofield
27 siblings, 3 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
A CXL region struct contains the physical address to work with.
Add a function for given a opaque cxl region struct returns the params
to be used for mapping such memory range.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/region.c | 16 ++++++++++++++++
drivers/cxl/cxl.h | 2 ++
include/cxl/cxl.h | 2 ++
3 files changed, 20 insertions(+)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index eff3ad788077..fa44a60549f7 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2663,6 +2663,22 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
return ERR_PTR(rc);
}
+int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
+ resource_size_t *end)
+{
+ if (!region)
+ return -ENODEV;
+
+ if (!region->params.res)
+ return -ENOSPC;
+
+ *start = region->params.res->start;
+ *end = region->params.res->end;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_get_region_params, CXL);
+
static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
{
return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index ee3385db5663..7b46d313e581 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -913,6 +913,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
+int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
+ resource_size_t *end);
/*
* Unit test builds overrides this to __weak, find the 'strong' version
* of these symbols in tools/testing/cxl/.
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 2a8ebabfc1dd..f14a3f292ad8 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -77,4 +77,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
bool avoid_dax);
int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
+int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
+ resource_size_t *end);
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* [PATCH v5 27/27] sfc: support pio mapping based on cxl
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (25 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 26/27] cxl: add function for obtaining params from a region alejandro.lucero-palau
@ 2024-11-18 16:44 ` alejandro.lucero-palau
2024-11-21 3:33 ` [PATCH v5 00/27] cxl: add type2 device basic support Alison Schofield
27 siblings, 0 replies; 99+ messages in thread
From: alejandro.lucero-palau @ 2024-11-18 16:44 UTC (permalink / raw)
To: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
With a device supporting CXL and successfully initialised, use the cxl
region to map the memory range and use this mapping for PIO buffers.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/net/ethernet/sfc/ef10.c | 49 +++++++++++++++++++++++----
drivers/net/ethernet/sfc/efx_cxl.c | 18 +++++++++-
drivers/net/ethernet/sfc/mcdi_pcol.h | 12 +++++++
drivers/net/ethernet/sfc/net_driver.h | 2 ++
drivers/net/ethernet/sfc/nic.h | 3 ++
5 files changed, 77 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index de131fc5fa0b..d19e42dd8dbd 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -24,6 +24,7 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <net/udp_tunnel.h>
+#include "efx_cxl.h"
/* Hardware control for EF10 architecture including 'Huntington'. */
@@ -177,6 +178,12 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
efx->num_mac_stats);
}
+ if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN)
+ nic_data->datapath_caps3 = 0;
+ else
+ nic_data->datapath_caps3 = MCDI_DWORD(outbuf,
+ GET_CAPABILITIES_V7_OUT_FLAGS3);
+
return 0;
}
@@ -919,6 +926,9 @@ static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
static void efx_ef10_remove(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
+#ifdef CONFIG_SFC_CXL
+ struct efx_probe_data *probe_data;
+#endif
int rc;
#ifdef CONFIG_SFC_SRIOV
@@ -949,7 +959,12 @@ static void efx_ef10_remove(struct efx_nic *efx)
efx_mcdi_rx_free_indir_table(efx);
+#ifdef CONFIG_SFC_CXL
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+ if (nic_data->wc_membase && !probe_data->cxl_pio_in_use)
+#else
if (nic_data->wc_membase)
+#endif
iounmap(nic_data->wc_membase);
rc = efx_mcdi_free_vis(efx);
@@ -1140,6 +1155,9 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
unsigned int channel_vis, pio_write_vi_base, max_vis;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
unsigned int uc_mem_map_size, wc_mem_map_size;
+#ifdef CONFIG_SFC_CXL
+ struct efx_probe_data *probe_data;
+#endif
void __iomem *membase;
int rc;
@@ -1263,8 +1281,27 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
iounmap(efx->membase);
efx->membase = membase;
- /* Set up the WC mapping if needed */
- if (wc_mem_map_size) {
+ if (!wc_mem_map_size) {
+ netif_dbg(efx, probe, efx->net_dev, "wc_mem_map_size is 0\n");
+ return 0;
+ }
+
+ /* Set up the WC mapping */
+
+#ifdef CONFIG_SFC_CXL
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+ if ((nic_data->datapath_caps3 &
+ (1 << MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_LBN)) &&
+ probe_data->cxl_pio_initialised) {
+ /* Using PIO through CXL mapping? */
+ nic_data->pio_write_base = probe_data->cxl->ctpio_cxl +
+ (pio_write_vi_base * efx->vi_stride +
+ ER_DZ_TX_PIOBUF - uc_mem_map_size);
+ probe_data->cxl_pio_in_use = true;
+ } else
+#endif
+ {
+ /* Using legacy PIO BAR mapping */
nic_data->wc_membase = ioremap_wc(efx->membase_phys +
uc_mem_map_size,
wc_mem_map_size);
@@ -1279,12 +1316,12 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
nic_data->wc_membase +
(pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF -
uc_mem_map_size);
-
- rc = efx_ef10_link_piobufs(efx);
- if (rc)
- efx_ef10_free_piobufs(efx);
}
+ rc = efx_ef10_link_piobufs(efx);
+ if (rc)
+ efx_ef10_free_piobufs(efx);
+
netif_dbg(efx, probe, efx->net_dev,
"memory BAR at %pa (virtual %p+%x UC, %p+%x WC)\n",
&efx->membase_phys, efx->membase, uc_mem_map_size,
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index de8d6bca9300..f727c53e287f 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -23,10 +23,10 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
struct efx_nic *efx = &probe_data->efx;
DECLARE_BITMAP(expected, CXL_MAX_CAPS);
DECLARE_BITMAP(found, CXL_MAX_CAPS);
+ resource_size_t max, start, end;
struct pci_dev *pci_dev;
struct efx_cxl *cxl;
struct resource res;
- resource_size_t max;
u16 dvsec;
int rc;
@@ -135,10 +135,25 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
goto err_region;
}
+ rc = cxl_get_region_params(cxl->efx_region, &start, &end);
+ if (rc) {
+ pci_err(pci_dev, "CXL getting regions params failed");
+ goto err_region_params;
+ }
+
+ cxl->ctpio_cxl = ioremap(start, end - start);
+ if (!cxl->ctpio_cxl) {
+ pci_err(pci_dev, "CXL ioremap region failed");
+ goto err_region_params;
+ }
+
probe_data->cxl = cxl;
+ probe_data->cxl_pio_initialised = true;
return 0;
+err_region_params:
+ cxl_accel_region_detach(cxl->cxled);
err_region:
cxl_dpa_free(cxl->cxled);
err3:
@@ -154,6 +169,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
void efx_cxl_exit(struct efx_probe_data *probe_data)
{
if (probe_data->cxl) {
+ iounmap(probe_data->cxl->ctpio_cxl);
cxl_accel_region_detach(probe_data->cxl->cxled);
cxl_dpa_free(probe_data->cxl->cxled);
cxl_release_resource(probe_data->cxl->cxlds, CXL_RES_RAM);
diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h
index cd297e19cddc..c158a1e8d01b 100644
--- a/drivers/net/ethernet/sfc/mcdi_pcol.h
+++ b/drivers/net/ethernet/sfc/mcdi_pcol.h
@@ -16799,6 +16799,9 @@
#define MC_CMD_GET_CAPABILITIES_V7_OUT_DYNAMIC_MPORT_JOURNAL_OFST 148
#define MC_CMD_GET_CAPABILITIES_V7_OUT_DYNAMIC_MPORT_JOURNAL_LBN 14
#define MC_CMD_GET_CAPABILITIES_V7_OUT_DYNAMIC_MPORT_JOURNAL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_WIDTH 1
/* MC_CMD_GET_CAPABILITIES_V8_OUT msgresponse */
#define MC_CMD_GET_CAPABILITIES_V8_OUT_LEN 160
@@ -17303,6 +17306,9 @@
#define MC_CMD_GET_CAPABILITIES_V8_OUT_DYNAMIC_MPORT_JOURNAL_OFST 148
#define MC_CMD_GET_CAPABILITIES_V8_OUT_DYNAMIC_MPORT_JOURNAL_LBN 14
#define MC_CMD_GET_CAPABILITIES_V8_OUT_DYNAMIC_MPORT_JOURNAL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_CXL_CONFIG_ENABLE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_CXL_CONFIG_ENABLE_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_CXL_CONFIG_ENABLE_WIDTH 1
/* These bits are reserved for communicating test-specific capabilities to
* host-side test software. All production drivers should treat this field as
* opaque.
@@ -17821,6 +17827,9 @@
#define MC_CMD_GET_CAPABILITIES_V9_OUT_DYNAMIC_MPORT_JOURNAL_OFST 148
#define MC_CMD_GET_CAPABILITIES_V9_OUT_DYNAMIC_MPORT_JOURNAL_LBN 14
#define MC_CMD_GET_CAPABILITIES_V9_OUT_DYNAMIC_MPORT_JOURNAL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_CXL_CONFIG_ENABLE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_CXL_CONFIG_ENABLE_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_CXL_CONFIG_ENABLE_WIDTH 1
/* These bits are reserved for communicating test-specific capabilities to
* host-side test software. All production drivers should treat this field as
* opaque.
@@ -18374,6 +18383,9 @@
#define MC_CMD_GET_CAPABILITIES_V10_OUT_DYNAMIC_MPORT_JOURNAL_OFST 148
#define MC_CMD_GET_CAPABILITIES_V10_OUT_DYNAMIC_MPORT_JOURNAL_LBN 14
#define MC_CMD_GET_CAPABILITIES_V10_OUT_DYNAMIC_MPORT_JOURNAL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V10_OUT_CXL_CONFIG_ENABLE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V10_OUT_CXL_CONFIG_ENABLE_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V10_OUT_CXL_CONFIG_ENABLE_WIDTH 1
/* These bits are reserved for communicating test-specific capabilities to
* host-side test software. All production drivers should treat this field as
* opaque.
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index efc6d90380b9..fcf3058f64d8 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1170,6 +1170,7 @@ struct efx_cxl;
* @efx: Efx NIC details
* @cxl: details of related cxl objects
* @cxl_pio_initialised: cxl initialization outcome.
++ * @cxl_pio_in_use: PIO using CXL mapping
*/
struct efx_probe_data {
struct pci_dev *pci_dev;
@@ -1177,6 +1178,7 @@ struct efx_probe_data {
#ifdef CONFIG_SFC_CXL
struct efx_cxl *cxl;
bool cxl_pio_initialised;
+ bool cxl_pio_in_use;
#endif
};
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 9fa5c4c713ab..c87cc9214690 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -152,6 +152,8 @@ enum {
* %MC_CMD_GET_CAPABILITIES response)
* @datapath_caps2: Further Capabilities of datapath firmware (FLAGS2 field of
* %MC_CMD_GET_CAPABILITIES response)
+ * @datapath_caps3: Further Capabilities of datapath firmware (FLAGS3 field of
+ * %MC_CMD_GET_CAPABILITIES response)
* @rx_dpcpu_fw_id: Firmware ID of the RxDPCPU
* @tx_dpcpu_fw_id: Firmware ID of the TxDPCPU
* @must_probe_vswitching: Flag: vswitching has yet to be setup after MC reboot
@@ -186,6 +188,7 @@ struct efx_ef10_nic_data {
bool must_check_datapath_caps;
u32 datapath_caps;
u32 datapath_caps2;
+ u32 datapath_caps3;
unsigned int rx_dpcpu_fw_id;
unsigned int tx_dpcpu_fw_id;
bool must_probe_vswitching;
--
2.17.1
^ permalink raw reply related [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
@ 2024-11-18 21:55 ` Dave Jiang
2024-11-20 13:40 ` Alejandro Lucero Palau
2024-11-20 23:07 ` Fan Ni
` (2 subsequent siblings)
3 siblings, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-18 21:55 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Differentiate Type3, aka memory expanders, from Type2, aka device
> accelerators, with a new function for initializing cxl_dev_state.
Please consider:
Differentiate CXL memory expanders (type 3) from CXL device
accelerators (type 2) with a new ...
>
> Create accessors to cxl_dev_state to be used by accel drivers.
>
> Based on previous work by Dan Williams [1]
>
> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
> drivers/cxl/core/pci.c | 1 +
> drivers/cxl/cxlpci.h | 16 ------------
> drivers/cxl/pci.c | 13 +++++++---
> include/cxl/cxl.h | 21 ++++++++++++++++
> include/cxl/pci.h | 23 ++++++++++++++++++
> 6 files changed, 105 insertions(+), 20 deletions(-)
> create mode 100644 include/cxl/cxl.h
> create mode 100644 include/cxl/pci.h
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index 84fefb76dafa..d083fd13a6dd 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. */
>
> +#include <cxl/cxl.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/firmware.h>
> #include <linux/device.h>
> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>
> static struct lock_class_key cxl_memdev_key;
>
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
> +{
> + struct cxl_dev_state *cxlds;
> +
> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
> + if (!cxlds)
> + return ERR_PTR(-ENOMEM);
> +
> + cxlds->dev = dev;
> + cxlds->type = CXL_DEVTYPE_DEVMEM;
> +
> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
> +
> + return cxlds;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
> +
> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> const struct file_operations *fops)
> {
> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
> return 0;
> }
>
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
> +{
> + cxlds->cxl_dvsec = dvsec;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
> +
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
> +{
> + cxlds->serial = serial;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
> +
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource type)
> +{
> + switch (type) {
> + case CXL_RES_DPA:
> + cxlds->dpa_res = res;
> + return 0;
> + case CXL_RES_RAM:
> + cxlds->ram_res = res;
> + return 0;
> + case CXL_RES_PMEM:
> + cxlds->pmem_res = res;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 420e4be85a1f..ff266e91ea71 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1,5 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
> +#include <cxl/pci.h>
> #include <linux/units.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/device.h>
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index 4da07727ab9c..eb59019fe5f3 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -14,22 +14,6 @@
> */
> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>
> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> -#define CXL_DVSEC_PCIE_DEVICE 0
> -#define CXL_DVSEC_CAP_OFFSET 0xA
> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> -#define CXL_DVSEC_CTRL_OFFSET 0xC
> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> -
> #define CXL_DVSEC_RANGE_MAX 2
>
> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 188412d45e0d..0b910ef52db7 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1,5 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
> #include <linux/unaligned.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/moduleparam.h>
> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> struct cxl_memdev *cxlmd;
> int i, rc, pmu_count;
> bool irq_avail;
> + u16 dvsec;
>
> /*
> * Double check the anonymous union trickery in struct cxl_regs
> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> pci_set_drvdata(pdev, cxlds);
>
> cxlds->rcd = is_cxl_restricted(pdev);
> - cxlds->serial = pci_get_dsn(pdev);
> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
> - if (!cxlds->cxl_dvsec)
> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
> + CXL_DVSEC_PCIE_DEVICE);
> + if (!dvsec)
> dev_warn(&pdev->dev,
> "Device DVSEC not present, skip CXL.mem init\n");
>
> + cxl_set_dvsec(cxlds, dvsec);
> +
> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> if (rc)
> return rc;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> new file mode 100644
> index 000000000000..19e5d883557a
> --- /dev/null
> +++ b/include/cxl/cxl.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
> +
> +#ifndef __CXL_H
> +#define __CXL_H
> +
> +#include <linux/ioport.h>
> +
> +enum cxl_resource {
> + CXL_RES_DPA,
> + CXL_RES_RAM,
> + CXL_RES_PMEM,
> +};
> +
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
> +
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource);
> +#endif
> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
> new file mode 100644
> index 000000000000..ad63560caa2c
> --- /dev/null
> +++ b/include/cxl/pci.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +
> +#ifndef __CXL_ACCEL_PCI_H
> +#define __CXL_ACCEL_PCI_H
> +
> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> +#define CXL_DVSEC_PCIE_DEVICE 0
> +#define CXL_DVSEC_CAP_OFFSET 0xA
> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> +#define CXL_DVSEC_CTRL_OFFSET 0xC
> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> +
> +#endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port
2024-11-18 16:44 ` [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port alejandro.lucero-palau
@ 2024-11-18 22:52 ` Dave Jiang
2024-11-19 12:28 ` Alejandro Lucero Palau
2024-11-22 20:44 ` Ben Cheatham
1 sibling, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-18 22:52 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Type2 devices have some Type3 functionalities as optional like an mbox
> or an hdm decoder, and CXL core needs a way to know what an CXL accelerator
> implements.
>
> Add a new field to cxl_dev_state for keeping device capabilities as discovered
> during initialization. Add same field to cxl_port as registers discovery
> is also used during port initialization.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/port.c | 11 +++++++----
> drivers/cxl/core/regs.c | 21 ++++++++++++++-------
> drivers/cxl/cxl.h | 9 ++++++---
> drivers/cxl/cxlmem.h | 2 ++
> drivers/cxl/pci.c | 10 ++++++----
> include/cxl/cxl.h | 30 ++++++++++++++++++++++++++++++
> 6 files changed, 65 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index af92c67bc954..5bc8490a199c 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -749,7 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
> }
>
> static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map,
> - resource_size_t component_reg_phys)
> + resource_size_t component_reg_phys, unsigned long *caps)
> {
> *map = (struct cxl_register_map) {
> .host = host,
> @@ -763,7 +763,7 @@ static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map
> map->reg_type = CXL_REGLOC_RBI_COMPONENT;
> map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
>
> - return cxl_setup_regs(map);
> + return cxl_setup_regs(map, caps);
> }
>
> static int cxl_port_setup_regs(struct cxl_port *port,
> @@ -772,7 +772,7 @@ static int cxl_port_setup_regs(struct cxl_port *port,
> if (dev_is_platform(port->uport_dev))
> return 0;
> return cxl_setup_comp_regs(&port->dev, &port->reg_map,
> - component_reg_phys);
> + component_reg_phys, port->capabilities);
> }
>
> static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
> @@ -789,7 +789,8 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
> * NULL.
> */
> rc = cxl_setup_comp_regs(dport->dport_dev, &dport->reg_map,
> - component_reg_phys);
> + component_reg_phys,
> + dport->port->capabilities);
> dport->reg_map.host = host;
> return rc;
> }
> @@ -851,6 +852,8 @@ static int cxl_port_add(struct cxl_port *port,
> port->reg_map = cxlds->reg_map;
> port->reg_map.host = &port->dev;
> cxlmd->endpoint = port;
> + bitmap_copy(port->capabilities, cxlds->capabilities,
> + CXL_MAX_CAPS);
> } else if (parent_dport) {
> rc = dev_set_name(dev, "port%d", port->id);
> if (rc)
> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
> index e1082e749c69..8287ec45b018 100644
> --- a/drivers/cxl/core/regs.c
> +++ b/drivers/cxl/core/regs.c
> @@ -4,6 +4,7 @@
> #include <linux/device.h>
> #include <linux/slab.h>
> #include <linux/pci.h>
> +#include <cxl/cxl.h>
> #include <cxlmem.h>
> #include <cxlpci.h>
> #include <pmu.h>
> @@ -36,7 +37,8 @@
> * Probe for component register information and return it in map object.
> */
> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> - struct cxl_component_reg_map *map)
> + struct cxl_component_reg_map *map,
> + unsigned long *caps)
> {
> int cap, cap_count;
> u32 cap_array;
> @@ -84,6 +86,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> decoder_cnt = cxl_hdm_decoder_count(hdr);
> length = 0x20 * decoder_cnt + 0x10;
> rmap = &map->hdm_decoder;
> + *caps |= BIT(CXL_DEV_CAP_HDM);
> break;
> }
> case CXL_CM_CAP_CAP_ID_RAS:
> @@ -91,6 +94,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> offset);
> length = CXL_RAS_CAPABILITY_LENGTH;
> rmap = &map->ras;
> + *caps |= BIT(CXL_DEV_CAP_RAS);
> break;
> default:
> dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
> @@ -117,7 +121,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);
> * Probe for device register information and return it in map object.
> */
> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> - struct cxl_device_reg_map *map)
> + struct cxl_device_reg_map *map, unsigned long *caps)
> {
> int cap, cap_count;
> u64 cap_array;
> @@ -146,10 +150,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
> dev_dbg(dev, "found Status capability (0x%x)\n", offset);
> rmap = &map->status;
> + *caps |= BIT(CXL_DEV_CAP_DEV_STATUS);
> break;
> case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
> dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
> rmap = &map->mbox;
> + *caps |= BIT(CXL_DEV_CAP_MAILBOX_PRIMARY);
> break;
> case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
> dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
> @@ -157,6 +163,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> case CXLDEV_CAP_CAP_ID_MEMDEV:
> dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
> rmap = &map->memdev;
> + *caps |= BIT(CXL_DEV_CAP_MEMDEV);
> break;
> default:
> if (cap_id >= 0x8000)
> @@ -421,7 +428,7 @@ static void cxl_unmap_regblock(struct cxl_register_map *map)
> map->base = NULL;
> }
>
> -static int cxl_probe_regs(struct cxl_register_map *map)
> +static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
> {
> struct cxl_component_reg_map *comp_map;
> struct cxl_device_reg_map *dev_map;
> @@ -431,12 +438,12 @@ static int cxl_probe_regs(struct cxl_register_map *map)
> switch (map->reg_type) {
> case CXL_REGLOC_RBI_COMPONENT:
> comp_map = &map->component_map;
> - cxl_probe_component_regs(host, base, comp_map);
> + cxl_probe_component_regs(host, base, comp_map, caps);
> dev_dbg(host, "Set up component registers\n");
> break;
> case CXL_REGLOC_RBI_MEMDEV:
> dev_map = &map->device_map;
> - cxl_probe_device_regs(host, base, dev_map);
> + cxl_probe_device_regs(host, base, dev_map, caps);
> if (!dev_map->status.valid || !dev_map->mbox.valid ||
> !dev_map->memdev.valid) {
> dev_err(host, "registers not found: %s%s%s\n",
> @@ -455,7 +462,7 @@ static int cxl_probe_regs(struct cxl_register_map *map)
> return 0;
> }
>
> -int cxl_setup_regs(struct cxl_register_map *map)
> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps)
> {
> int rc;
>
> @@ -463,7 +470,7 @@ int cxl_setup_regs(struct cxl_register_map *map)
> if (rc)
> return rc;
>
> - rc = cxl_probe_regs(map);
> + rc = cxl_probe_regs(map, caps);
> cxl_unmap_regblock(map);
>
> return rc;
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index a2be05fd7aa2..e5f918be6fe4 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -4,6 +4,7 @@
> #ifndef __CXL_H__
> #define __CXL_H__
>
> +#include <cxl/cxl.h>
> #include <linux/libnvdimm.h>
> #include <linux/bitfield.h>
> #include <linux/notifier.h>
> @@ -284,9 +285,9 @@ struct cxl_register_map {
> };
>
> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> - struct cxl_component_reg_map *map);
> + struct cxl_component_reg_map *map, unsigned long *caps);
> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> - struct cxl_device_reg_map *map);
> + struct cxl_device_reg_map *map, unsigned long *caps);
> int cxl_map_component_regs(const struct cxl_register_map *map,
> struct cxl_component_regs *regs,
> unsigned long map_mask);
> @@ -300,7 +301,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
> struct cxl_register_map *map, int index);
> int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
> struct cxl_register_map *map);
> -int cxl_setup_regs(struct cxl_register_map *map);
> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps);
> struct cxl_dport;
> resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
> struct cxl_dport *dport);
> @@ -600,6 +601,7 @@ struct cxl_dax_region {
> * @cdat: Cached CDAT data
> * @cdat_available: Should a CDAT attribute be available in sysfs
> * @pci_latency: Upstream latency in picoseconds
> + * @capabilities: those capabilities as defined in device mapped registers
> */
> struct cxl_port {
> struct device dev;
> @@ -623,6 +625,7 @@ struct cxl_port {
> } cdat;
> bool cdat_available;
> long pci_latency;
> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
> };
>
> /**
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 2a25d1957ddb..4c1c53c29544 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -428,6 +428,7 @@ struct cxl_dpa_perf {
> * @serial: PCIe Device Serial Number
> * @type: Generic Memory Class device or Vendor Specific Memory device
> * @cxl_mbox: CXL mailbox context
> + * @capabilities: those capabilities as defined in device mapped registers
> */
> struct cxl_dev_state {
> struct device *dev;
> @@ -443,6 +444,7 @@ struct cxl_dev_state {
> u64 serial;
> enum cxl_devtype type;
> struct cxl_mailbox cxl_mbox;
> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
> };
>
> static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 0b910ef52db7..528d4ca79fd1 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -504,7 +504,8 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
> }
>
> static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> - struct cxl_register_map *map)
> + struct cxl_register_map *map,
> + unsigned long *caps)
> {
> int rc;
>
> @@ -521,7 +522,7 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> if (rc)
> return rc;
>
> - return cxl_setup_regs(map);
> + return cxl_setup_regs(map, caps);
> }
>
> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
> @@ -848,7 +849,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>
> cxl_set_dvsec(cxlds, dvsec);
>
> - rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
> + cxlds->capabilities);
> if (rc)
> return rc;
>
> @@ -861,7 +863,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> * still be useful for management functions so don't return an error.
> */
> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
> - &cxlds->reg_map);
> + &cxlds->reg_map, cxlds->capabilities);
> if (rc)
> dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
> else if (!cxlds->reg_map.component_map.ras.valid)
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 19e5d883557a..dcc9ec8a0aec 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -12,6 +12,36 @@ enum cxl_resource {
> CXL_RES_PMEM,
> };
>
> +/* Capabilities as defined for:
> + *
> + * Component Registers (Table 8-22 CXL 3.1 specification)
> + * Device Registers (8.2.8.2.1 CXL 3.1 specification)
> + */
> +
> +enum cxl_dev_cap {
> + /* capabilities from Component Registers */
> + CXL_DEV_CAP_RAS,
> + CXL_DEV_CAP_SEC,
There are a few caps that does not seem to be used yet. Should we not bother defining them until they are being used?
> + CXL_DEV_CAP_LINK,
> + CXL_DEV_CAP_HDM,
> + CXL_DEV_CAP_SEC_EXT,
> + CXL_DEV_CAP_IDE,
> + CXL_DEV_CAP_SNOOP_FILTER,
> + CXL_DEV_CAP_TIMEOUT_AND_ISOLATION,
> + CXL_DEV_CAP_CACHEMEM_EXT,
> + CXL_DEV_CAP_BI_ROUTE_TABLE,
> + CXL_DEV_CAP_BI_DECODER,
> + CXL_DEV_CAP_CACHEID_ROUTE_TABLE,
> + CXL_DEV_CAP_CACHEID_DECODER,
> + CXL_DEV_CAP_HDM_EXT,
> + CXL_DEV_CAP_METADATA_EXT,
> + /* capabilities from Device Registers */
> + CXL_DEV_CAP_DEV_STATUS,
> + CXL_DEV_CAP_MAILBOX_PRIMARY,
> + CXL_DEV_CAP_MEMDEV,
> + CXL_MAX_CAPS = 32
This is changed to 64 in the next patch. Should it just be set to 64 here? I assume you just wanted a bitmap that's u64 long?
DJ
> +};
> +
> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>
> void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 05/27] cxl: move pci generic code
2024-11-18 16:44 ` [PATCH v5 05/27] cxl: move pci generic code alejandro.lucero-palau
@ 2024-11-18 22:57 ` Dave Jiang
2024-11-22 20:44 ` Ben Cheatham
1 sibling, 0 replies; 99+ messages in thread
From: Dave Jiang @ 2024-11-18 22:57 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Inside cxl/core/pci.c there are helpers for CXL PCIe initialization
> meanwhile cxl/pci.c implements the functionality for a Type3 device
> initialization.
>
> Move helper functions from cxl/pci.c to cxl/core/pci.c in order to be
> exported and shared with CXL Type2 device initialization.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/pci.c | 62 ++++++++++++++++++++++++++++++++++++++++++
> drivers/cxl/cxlpci.h | 3 ++
> drivers/cxl/pci.c | 58 ---------------------------------------
> 3 files changed, 65 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index a1942b7be0bc..bfc5e96e3cb9 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1034,6 +1034,68 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
> }
> EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL);
>
> +/*
> + * Assume that any RCIEP that emits the CXL memory expander class code
> + * is an RCD
> + */
> +bool is_cxl_restricted(struct pci_dev *pdev)
> +{
> + return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
> +}
> +EXPORT_SYMBOL_NS_GPL(is_cxl_restricted, CXL);
> +
> +static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
> + struct cxl_register_map *map)
> +{
> + struct cxl_port *port;
> + struct cxl_dport *dport;
> + resource_size_t component_reg_phys;
> +
> + *map = (struct cxl_register_map) {
> + .host = &pdev->dev,
> + .resource = CXL_RESOURCE_NONE,
> + };
> +
> + port = cxl_pci_find_port(pdev, &dport);
> + if (!port)
> + return -EPROBE_DEFER;
> +
> + component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
> +
> + put_device(&port->dev);
> +
> + if (component_reg_phys == CXL_RESOURCE_NONE)
> + return -ENXIO;
> +
> + map->resource = component_reg_phys;
> + map->reg_type = CXL_REGLOC_RBI_COMPONENT;
> + map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
> +
> + return 0;
> +}
> +
> +int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> + struct cxl_register_map *map, unsigned long *caps)
> +{
> + int rc;
> +
> + rc = cxl_find_regblock(pdev, type, map);
> +
> + /*
> + * If the Register Locator DVSEC does not exist, check if it
> + * is an RCH and try to extract the Component Registers from
> + * an RCRB.
> + */
> + if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev))
> + rc = cxl_rcrb_get_comp_regs(pdev, map);
> +
> + if (rc)
> + return rc;
> +
> + return cxl_setup_regs(map, caps);
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, CXL);
> +
> int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
> {
> int speed, bw;
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index eb59019fe5f3..985cca3c3350 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -113,4 +113,7 @@ void read_cdat_data(struct cxl_port *port);
> void cxl_cor_error_detected(struct pci_dev *pdev);
> pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
> pci_channel_state_t state);
> +bool is_cxl_restricted(struct pci_dev *pdev);
> +int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> + struct cxl_register_map *map, unsigned long *caps);
> #endif /* __CXL_PCI_H__ */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 5de1473a79da..caa7e101e063 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -467,64 +467,6 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail)
> return 0;
> }
>
> -/*
> - * Assume that any RCIEP that emits the CXL memory expander class code
> - * is an RCD
> - */
> -static bool is_cxl_restricted(struct pci_dev *pdev)
> -{
> - return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
> -}
> -
> -static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
> - struct cxl_register_map *map)
> -{
> - struct cxl_dport *dport;
> - resource_size_t component_reg_phys;
> -
> - *map = (struct cxl_register_map) {
> - .host = &pdev->dev,
> - .resource = CXL_RESOURCE_NONE,
> - };
> -
> - struct cxl_port *port __free(put_cxl_port) =
> - cxl_pci_find_port(pdev, &dport);
> - if (!port)
> - return -EPROBE_DEFER;
> -
> - component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
> - if (component_reg_phys == CXL_RESOURCE_NONE)
> - return -ENXIO;
> -
> - map->resource = component_reg_phys;
> - map->reg_type = CXL_REGLOC_RBI_COMPONENT;
> - map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
> -
> - return 0;
> -}
> -
> -static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> - struct cxl_register_map *map,
> - unsigned long *caps)
> -{
> - int rc;
> -
> - rc = cxl_find_regblock(pdev, type, map);
> -
> - /*
> - * If the Register Locator DVSEC does not exist, check if it
> - * is an RCH and try to extract the Component Registers from
> - * an RCRB.
> - */
> - if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev))
> - rc = cxl_rcrb_get_comp_regs(pdev, map);
> -
> - if (rc)
> - return rc;
> -
> - return cxl_setup_regs(map, caps);
> -}
> -
> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
> {
> struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 06/27] cxl: add function for type2 cxl regs setup
2024-11-18 16:44 ` [PATCH v5 06/27] cxl: add function for type2 cxl regs setup alejandro.lucero-palau
@ 2024-11-18 23:32 ` Dave Jiang
2024-11-21 22:34 ` Alison Schofield
1 sibling, 0 replies; 99+ messages in thread
From: Dave Jiang @ 2024-11-18 23:32 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Create a new function for a type2 device initialising
> cxl_dev_state struct regarding cxl regs setup and mapping.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/pci.c | 47 ++++++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 2 ++
> 2 files changed, 49 insertions(+)
>
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index bfc5e96e3cb9..8b9aa2c578e1 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1096,6 +1096,53 @@ int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> }
> EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, CXL);
>
> +static int cxl_pci_setup_memdev_regs(struct pci_dev *pdev,
> + struct cxl_dev_state *cxlds)
> +{
> + struct cxl_register_map map;
> + int rc;
> +
> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
> + cxlds->capabilities);
> + /*
> + * This call returning a non-zero value is not considered an error since
> + * these regs are not mandatory for Type2. If they do exist then mapping
> + * them should not fail.
> + */
> + if (rc)
> + return 0;
> +
> + return cxl_map_device_regs(&map, &cxlds->regs.device_regs);
> +}
> +
> +int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds)
> +{
> + int rc;
> +
> + rc = cxl_pci_setup_memdev_regs(pdev, cxlds);
> + if (rc)
> + return rc;
> +
> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
> + &cxlds->reg_map, cxlds->capabilities);
> + if (rc) {
> + dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
> + return rc;
> + }
> +
> + if (!test_bit(CXL_CM_CAP_CAP_ID_RAS, cxlds->capabilities))
> + return rc;
> +
> + rc = cxl_map_component_regs(&cxlds->reg_map,
> + &cxlds->regs.component,
> + BIT(CXL_CM_CAP_CAP_ID_RAS));
> + if (rc)
> + dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
> +
> + return rc;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_pci_accel_setup_regs, CXL);
> +
> int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
> {
> int speed, bw;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index ab243ab8024f..a88d3475e551 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -5,6 +5,7 @@
> #define __CXL_H
>
> #include <linux/ioport.h>
> +#include <linux/pci.h>
>
> enum cxl_resource {
> CXL_RES_DPA,
> @@ -52,4 +53,5 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
> unsigned long *expected_caps,
> unsigned long *current_caps,
> bool is_subset);
> +int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port
2024-11-18 22:52 ` Dave Jiang
@ 2024-11-19 12:28 ` Alejandro Lucero Palau
2024-11-19 15:53 ` Dave Jiang
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-19 12:28 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On 11/18/24 22:52, Dave Jiang wrote:
>
> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Type2 devices have some Type3 functionalities as optional like an mbox
>> or an hdm decoder, and CXL core needs a way to know what an CXL accelerator
>> implements.
>>
>> Add a new field to cxl_dev_state for keeping device capabilities as discovered
>> during initialization. Add same field to cxl_port as registers discovery
>> is also used during port initialization.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/port.c | 11 +++++++----
>> drivers/cxl/core/regs.c | 21 ++++++++++++++-------
>> drivers/cxl/cxl.h | 9 ++++++---
>> drivers/cxl/cxlmem.h | 2 ++
>> drivers/cxl/pci.c | 10 ++++++----
>> include/cxl/cxl.h | 30 ++++++++++++++++++++++++++++++
>> 6 files changed, 65 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
>> index af92c67bc954..5bc8490a199c 100644
>> --- a/drivers/cxl/core/port.c
>> +++ b/drivers/cxl/core/port.c
>> @@ -749,7 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
>> }
>>
>> static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map,
>> - resource_size_t component_reg_phys)
>> + resource_size_t component_reg_phys, unsigned long *caps)
>> {
>> *map = (struct cxl_register_map) {
>> .host = host,
>> @@ -763,7 +763,7 @@ static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map
>> map->reg_type = CXL_REGLOC_RBI_COMPONENT;
>> map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
>>
>> - return cxl_setup_regs(map);
>> + return cxl_setup_regs(map, caps);
>> }
>>
>> static int cxl_port_setup_regs(struct cxl_port *port,
>> @@ -772,7 +772,7 @@ static int cxl_port_setup_regs(struct cxl_port *port,
>> if (dev_is_platform(port->uport_dev))
>> return 0;
>> return cxl_setup_comp_regs(&port->dev, &port->reg_map,
>> - component_reg_phys);
>> + component_reg_phys, port->capabilities);
>> }
>>
>> static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
>> @@ -789,7 +789,8 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
>> * NULL.
>> */
>> rc = cxl_setup_comp_regs(dport->dport_dev, &dport->reg_map,
>> - component_reg_phys);
>> + component_reg_phys,
>> + dport->port->capabilities);
>> dport->reg_map.host = host;
>> return rc;
>> }
>> @@ -851,6 +852,8 @@ static int cxl_port_add(struct cxl_port *port,
>> port->reg_map = cxlds->reg_map;
>> port->reg_map.host = &port->dev;
>> cxlmd->endpoint = port;
>> + bitmap_copy(port->capabilities, cxlds->capabilities,
>> + CXL_MAX_CAPS);
>> } else if (parent_dport) {
>> rc = dev_set_name(dev, "port%d", port->id);
>> if (rc)
>> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
>> index e1082e749c69..8287ec45b018 100644
>> --- a/drivers/cxl/core/regs.c
>> +++ b/drivers/cxl/core/regs.c
>> @@ -4,6 +4,7 @@
>> #include <linux/device.h>
>> #include <linux/slab.h>
>> #include <linux/pci.h>
>> +#include <cxl/cxl.h>
>> #include <cxlmem.h>
>> #include <cxlpci.h>
>> #include <pmu.h>
>> @@ -36,7 +37,8 @@
>> * Probe for component register information and return it in map object.
>> */
>> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>> - struct cxl_component_reg_map *map)
>> + struct cxl_component_reg_map *map,
>> + unsigned long *caps)
>> {
>> int cap, cap_count;
>> u32 cap_array;
>> @@ -84,6 +86,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>> decoder_cnt = cxl_hdm_decoder_count(hdr);
>> length = 0x20 * decoder_cnt + 0x10;
>> rmap = &map->hdm_decoder;
>> + *caps |= BIT(CXL_DEV_CAP_HDM);
>> break;
>> }
>> case CXL_CM_CAP_CAP_ID_RAS:
>> @@ -91,6 +94,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>> offset);
>> length = CXL_RAS_CAPABILITY_LENGTH;
>> rmap = &map->ras;
>> + *caps |= BIT(CXL_DEV_CAP_RAS);
>> break;
>> default:
>> dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
>> @@ -117,7 +121,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);
>> * Probe for device register information and return it in map object.
>> */
>> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>> - struct cxl_device_reg_map *map)
>> + struct cxl_device_reg_map *map, unsigned long *caps)
>> {
>> int cap, cap_count;
>> u64 cap_array;
>> @@ -146,10 +150,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>> case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
>> dev_dbg(dev, "found Status capability (0x%x)\n", offset);
>> rmap = &map->status;
>> + *caps |= BIT(CXL_DEV_CAP_DEV_STATUS);
>> break;
>> case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
>> dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
>> rmap = &map->mbox;
>> + *caps |= BIT(CXL_DEV_CAP_MAILBOX_PRIMARY);
>> break;
>> case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
>> dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
>> @@ -157,6 +163,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>> case CXLDEV_CAP_CAP_ID_MEMDEV:
>> dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
>> rmap = &map->memdev;
>> + *caps |= BIT(CXL_DEV_CAP_MEMDEV);
>> break;
>> default:
>> if (cap_id >= 0x8000)
>> @@ -421,7 +428,7 @@ static void cxl_unmap_regblock(struct cxl_register_map *map)
>> map->base = NULL;
>> }
>>
>> -static int cxl_probe_regs(struct cxl_register_map *map)
>> +static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
>> {
>> struct cxl_component_reg_map *comp_map;
>> struct cxl_device_reg_map *dev_map;
>> @@ -431,12 +438,12 @@ static int cxl_probe_regs(struct cxl_register_map *map)
>> switch (map->reg_type) {
>> case CXL_REGLOC_RBI_COMPONENT:
>> comp_map = &map->component_map;
>> - cxl_probe_component_regs(host, base, comp_map);
>> + cxl_probe_component_regs(host, base, comp_map, caps);
>> dev_dbg(host, "Set up component registers\n");
>> break;
>> case CXL_REGLOC_RBI_MEMDEV:
>> dev_map = &map->device_map;
>> - cxl_probe_device_regs(host, base, dev_map);
>> + cxl_probe_device_regs(host, base, dev_map, caps);
>> if (!dev_map->status.valid || !dev_map->mbox.valid ||
>> !dev_map->memdev.valid) {
>> dev_err(host, "registers not found: %s%s%s\n",
>> @@ -455,7 +462,7 @@ static int cxl_probe_regs(struct cxl_register_map *map)
>> return 0;
>> }
>>
>> -int cxl_setup_regs(struct cxl_register_map *map)
>> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps)
>> {
>> int rc;
>>
>> @@ -463,7 +470,7 @@ int cxl_setup_regs(struct cxl_register_map *map)
>> if (rc)
>> return rc;
>>
>> - rc = cxl_probe_regs(map);
>> + rc = cxl_probe_regs(map, caps);
>> cxl_unmap_regblock(map);
>>
>> return rc;
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index a2be05fd7aa2..e5f918be6fe4 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -4,6 +4,7 @@
>> #ifndef __CXL_H__
>> #define __CXL_H__
>>
>> +#include <cxl/cxl.h>
>> #include <linux/libnvdimm.h>
>> #include <linux/bitfield.h>
>> #include <linux/notifier.h>
>> @@ -284,9 +285,9 @@ struct cxl_register_map {
>> };
>>
>> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>> - struct cxl_component_reg_map *map);
>> + struct cxl_component_reg_map *map, unsigned long *caps);
>> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>> - struct cxl_device_reg_map *map);
>> + struct cxl_device_reg_map *map, unsigned long *caps);
>> int cxl_map_component_regs(const struct cxl_register_map *map,
>> struct cxl_component_regs *regs,
>> unsigned long map_mask);
>> @@ -300,7 +301,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
>> struct cxl_register_map *map, int index);
>> int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
>> struct cxl_register_map *map);
>> -int cxl_setup_regs(struct cxl_register_map *map);
>> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps);
>> struct cxl_dport;
>> resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
>> struct cxl_dport *dport);
>> @@ -600,6 +601,7 @@ struct cxl_dax_region {
>> * @cdat: Cached CDAT data
>> * @cdat_available: Should a CDAT attribute be available in sysfs
>> * @pci_latency: Upstream latency in picoseconds
>> + * @capabilities: those capabilities as defined in device mapped registers
>> */
>> struct cxl_port {
>> struct device dev;
>> @@ -623,6 +625,7 @@ struct cxl_port {
>> } cdat;
>> bool cdat_available;
>> long pci_latency;
>> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
>> };
>>
>> /**
>> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
>> index 2a25d1957ddb..4c1c53c29544 100644
>> --- a/drivers/cxl/cxlmem.h
>> +++ b/drivers/cxl/cxlmem.h
>> @@ -428,6 +428,7 @@ struct cxl_dpa_perf {
>> * @serial: PCIe Device Serial Number
>> * @type: Generic Memory Class device or Vendor Specific Memory device
>> * @cxl_mbox: CXL mailbox context
>> + * @capabilities: those capabilities as defined in device mapped registers
>> */
>> struct cxl_dev_state {
>> struct device *dev;
>> @@ -443,6 +444,7 @@ struct cxl_dev_state {
>> u64 serial;
>> enum cxl_devtype type;
>> struct cxl_mailbox cxl_mbox;
>> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
>> };
>>
>> static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>> index 0b910ef52db7..528d4ca79fd1 100644
>> --- a/drivers/cxl/pci.c
>> +++ b/drivers/cxl/pci.c
>> @@ -504,7 +504,8 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
>> }
>>
>> static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
>> - struct cxl_register_map *map)
>> + struct cxl_register_map *map,
>> + unsigned long *caps)
>> {
>> int rc;
>>
>> @@ -521,7 +522,7 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
>> if (rc)
>> return rc;
>>
>> - return cxl_setup_regs(map);
>> + return cxl_setup_regs(map, caps);
>> }
>>
>> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
>> @@ -848,7 +849,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>
>> cxl_set_dvsec(cxlds, dvsec);
>>
>> - rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
>> + cxlds->capabilities);
>> if (rc)
>> return rc;
>>
>> @@ -861,7 +863,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> * still be useful for management functions so don't return an error.
>> */
>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
>> - &cxlds->reg_map);
>> + &cxlds->reg_map, cxlds->capabilities);
>> if (rc)
>> dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
>> else if (!cxlds->reg_map.component_map.ras.valid)
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 19e5d883557a..dcc9ec8a0aec 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -12,6 +12,36 @@ enum cxl_resource {
>> CXL_RES_PMEM,
>> };
>>
>> +/* Capabilities as defined for:
>> + *
>> + * Component Registers (Table 8-22 CXL 3.1 specification)
>> + * Device Registers (8.2.8.2.1 CXL 3.1 specification)
>> + */
>> +
>> +enum cxl_dev_cap {
>> + /* capabilities from Component Registers */
>> + CXL_DEV_CAP_RAS,
>> + CXL_DEV_CAP_SEC,
> There are a few caps that does not seem to be used yet. Should we not bother defining them until they are being used?
Jonathan Cameron did suggest it as well, but I think, only when dealing
with capabilities discovery and checking.
It is weird to me to mention the specs here and just list a few of the
capabilities defined, but I will remove those not used yet if that is
the general view.
>> + CXL_DEV_CAP_LINK,
>> + CXL_DEV_CAP_HDM,
>> + CXL_DEV_CAP_SEC_EXT,
>> + CXL_DEV_CAP_IDE,
>> + CXL_DEV_CAP_SNOOP_FILTER,
>> + CXL_DEV_CAP_TIMEOUT_AND_ISOLATION,
>> + CXL_DEV_CAP_CACHEMEM_EXT,
>> + CXL_DEV_CAP_BI_ROUTE_TABLE,
>> + CXL_DEV_CAP_BI_DECODER,
>> + CXL_DEV_CAP_CACHEID_ROUTE_TABLE,
>> + CXL_DEV_CAP_CACHEID_DECODER,
>> + CXL_DEV_CAP_HDM_EXT,
>> + CXL_DEV_CAP_METADATA_EXT,
>> + /* capabilities from Device Registers */
>> + CXL_DEV_CAP_DEV_STATUS,
>> + CXL_DEV_CAP_MAILBOX_PRIMARY,
>> + CXL_DEV_CAP_MEMDEV,
>> + CXL_MAX_CAPS = 32
> This is changed to 64 in the next patch. Should it just be set to 64 here? I assume you just wanted a bitmap that's u64 long?
Oh, yes, I should change it here.
It was suggested to use CXL_MAX_CAPS for clearing/zeroing new
allocated bitmaps instead of BITS_PER_TYPE(unsigned long) as in v4, and
for that to work, CXL_MAX_CAPS needs to be defined taking into account
the size of unsigned long, which is the minimum unit for BITMAP. For
x86_64 that is 8 bytes. Otherwise the clearing would leave the upper 32
bits untouched.
Thanks!
> DJ
>
>> +};
>> +
>> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>>
>> void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port
2024-11-19 12:28 ` Alejandro Lucero Palau
@ 2024-11-19 15:53 ` Dave Jiang
2024-11-20 13:41 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-19 15:53 UTC (permalink / raw)
To: Alejandro Lucero Palau, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On 11/19/24 5:28 AM, Alejandro Lucero Palau wrote:
>
> On 11/18/24 22:52, Dave Jiang wrote:
>>
>> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>>> From: Alejandro Lucero <alucerop@amd.com>
>>>
>>> Type2 devices have some Type3 functionalities as optional like an mbox
>>> or an hdm decoder, and CXL core needs a way to know what an CXL accelerator
>>> implements.
>>>
>>> Add a new field to cxl_dev_state for keeping device capabilities as discovered
>>> during initialization. Add same field to cxl_port as registers discovery
>>> is also used during port initialization.
>>>
>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>> ---
>>> drivers/cxl/core/port.c | 11 +++++++----
>>> drivers/cxl/core/regs.c | 21 ++++++++++++++-------
>>> drivers/cxl/cxl.h | 9 ++++++---
>>> drivers/cxl/cxlmem.h | 2 ++
>>> drivers/cxl/pci.c | 10 ++++++----
>>> include/cxl/cxl.h | 30 ++++++++++++++++++++++++++++++
>>> 6 files changed, 65 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
>>> index af92c67bc954..5bc8490a199c 100644
>>> --- a/drivers/cxl/core/port.c
>>> +++ b/drivers/cxl/core/port.c
>>> @@ -749,7 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
>>> }
>>> static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map,
>>> - resource_size_t component_reg_phys)
>>> + resource_size_t component_reg_phys, unsigned long *caps)
>>> {
>>> *map = (struct cxl_register_map) {
>>> .host = host,
>>> @@ -763,7 +763,7 @@ static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map
>>> map->reg_type = CXL_REGLOC_RBI_COMPONENT;
>>> map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
>>> - return cxl_setup_regs(map);
>>> + return cxl_setup_regs(map, caps);
>>> }
>>> static int cxl_port_setup_regs(struct cxl_port *port,
>>> @@ -772,7 +772,7 @@ static int cxl_port_setup_regs(struct cxl_port *port,
>>> if (dev_is_platform(port->uport_dev))
>>> return 0;
>>> return cxl_setup_comp_regs(&port->dev, &port->reg_map,
>>> - component_reg_phys);
>>> + component_reg_phys, port->capabilities);
>>> }
>>> static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
>>> @@ -789,7 +789,8 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
>>> * NULL.
>>> */
>>> rc = cxl_setup_comp_regs(dport->dport_dev, &dport->reg_map,
>>> - component_reg_phys);
>>> + component_reg_phys,
>>> + dport->port->capabilities);
>>> dport->reg_map.host = host;
>>> return rc;
>>> }
>>> @@ -851,6 +852,8 @@ static int cxl_port_add(struct cxl_port *port,
>>> port->reg_map = cxlds->reg_map;
>>> port->reg_map.host = &port->dev;
>>> cxlmd->endpoint = port;
>>> + bitmap_copy(port->capabilities, cxlds->capabilities,
>>> + CXL_MAX_CAPS);
>>> } else if (parent_dport) {
>>> rc = dev_set_name(dev, "port%d", port->id);
>>> if (rc)
>>> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
>>> index e1082e749c69..8287ec45b018 100644
>>> --- a/drivers/cxl/core/regs.c
>>> +++ b/drivers/cxl/core/regs.c
>>> @@ -4,6 +4,7 @@
>>> #include <linux/device.h>
>>> #include <linux/slab.h>
>>> #include <linux/pci.h>
>>> +#include <cxl/cxl.h>
>>> #include <cxlmem.h>
>>> #include <cxlpci.h>
>>> #include <pmu.h>
>>> @@ -36,7 +37,8 @@
>>> * Probe for component register information and return it in map object.
>>> */
>>> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>> - struct cxl_component_reg_map *map)
>>> + struct cxl_component_reg_map *map,
>>> + unsigned long *caps)
>>> {
>>> int cap, cap_count;
>>> u32 cap_array;
>>> @@ -84,6 +86,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>> decoder_cnt = cxl_hdm_decoder_count(hdr);
>>> length = 0x20 * decoder_cnt + 0x10;
>>> rmap = &map->hdm_decoder;
>>> + *caps |= BIT(CXL_DEV_CAP_HDM);
>>> break;
>>> }
>>> case CXL_CM_CAP_CAP_ID_RAS:
>>> @@ -91,6 +94,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>> offset);
>>> length = CXL_RAS_CAPABILITY_LENGTH;
>>> rmap = &map->ras;
>>> + *caps |= BIT(CXL_DEV_CAP_RAS);
>>> break;
>>> default:
>>> dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
>>> @@ -117,7 +121,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);
>>> * Probe for device register information and return it in map object.
>>> */
>>> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>> - struct cxl_device_reg_map *map)
>>> + struct cxl_device_reg_map *map, unsigned long *caps)
>>> {
>>> int cap, cap_count;
>>> u64 cap_array;
>>> @@ -146,10 +150,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>> case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
>>> dev_dbg(dev, "found Status capability (0x%x)\n", offset);
>>> rmap = &map->status;
>>> + *caps |= BIT(CXL_DEV_CAP_DEV_STATUS);
>>> break;
>>> case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
>>> dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
>>> rmap = &map->mbox;
>>> + *caps |= BIT(CXL_DEV_CAP_MAILBOX_PRIMARY);
>>> break;
>>> case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
>>> dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
>>> @@ -157,6 +163,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>> case CXLDEV_CAP_CAP_ID_MEMDEV:
>>> dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
>>> rmap = &map->memdev;
>>> + *caps |= BIT(CXL_DEV_CAP_MEMDEV);
>>> break;
>>> default:
>>> if (cap_id >= 0x8000)
>>> @@ -421,7 +428,7 @@ static void cxl_unmap_regblock(struct cxl_register_map *map)
>>> map->base = NULL;
>>> }
>>> -static int cxl_probe_regs(struct cxl_register_map *map)
>>> +static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
>>> {
>>> struct cxl_component_reg_map *comp_map;
>>> struct cxl_device_reg_map *dev_map;
>>> @@ -431,12 +438,12 @@ static int cxl_probe_regs(struct cxl_register_map *map)
>>> switch (map->reg_type) {
>>> case CXL_REGLOC_RBI_COMPONENT:
>>> comp_map = &map->component_map;
>>> - cxl_probe_component_regs(host, base, comp_map);
>>> + cxl_probe_component_regs(host, base, comp_map, caps);
>>> dev_dbg(host, "Set up component registers\n");
>>> break;
>>> case CXL_REGLOC_RBI_MEMDEV:
>>> dev_map = &map->device_map;
>>> - cxl_probe_device_regs(host, base, dev_map);
>>> + cxl_probe_device_regs(host, base, dev_map, caps);
>>> if (!dev_map->status.valid || !dev_map->mbox.valid ||
>>> !dev_map->memdev.valid) {
>>> dev_err(host, "registers not found: %s%s%s\n",
>>> @@ -455,7 +462,7 @@ static int cxl_probe_regs(struct cxl_register_map *map)
>>> return 0;
>>> }
>>> -int cxl_setup_regs(struct cxl_register_map *map)
>>> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps)
>>> {
>>> int rc;
>>> @@ -463,7 +470,7 @@ int cxl_setup_regs(struct cxl_register_map *map)
>>> if (rc)
>>> return rc;
>>> - rc = cxl_probe_regs(map);
>>> + rc = cxl_probe_regs(map, caps);
>>> cxl_unmap_regblock(map);
>>> return rc;
>>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>>> index a2be05fd7aa2..e5f918be6fe4 100644
>>> --- a/drivers/cxl/cxl.h
>>> +++ b/drivers/cxl/cxl.h
>>> @@ -4,6 +4,7 @@
>>> #ifndef __CXL_H__
>>> #define __CXL_H__
>>> +#include <cxl/cxl.h>
>>> #include <linux/libnvdimm.h>
>>> #include <linux/bitfield.h>
>>> #include <linux/notifier.h>
>>> @@ -284,9 +285,9 @@ struct cxl_register_map {
>>> };
>>> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>> - struct cxl_component_reg_map *map);
>>> + struct cxl_component_reg_map *map, unsigned long *caps);
>>> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>> - struct cxl_device_reg_map *map);
>>> + struct cxl_device_reg_map *map, unsigned long *caps);
>>> int cxl_map_component_regs(const struct cxl_register_map *map,
>>> struct cxl_component_regs *regs,
>>> unsigned long map_mask);
>>> @@ -300,7 +301,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
>>> struct cxl_register_map *map, int index);
>>> int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
>>> struct cxl_register_map *map);
>>> -int cxl_setup_regs(struct cxl_register_map *map);
>>> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps);
>>> struct cxl_dport;
>>> resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
>>> struct cxl_dport *dport);
>>> @@ -600,6 +601,7 @@ struct cxl_dax_region {
>>> * @cdat: Cached CDAT data
>>> * @cdat_available: Should a CDAT attribute be available in sysfs
>>> * @pci_latency: Upstream latency in picoseconds
>>> + * @capabilities: those capabilities as defined in device mapped registers
>>> */
>>> struct cxl_port {
>>> struct device dev;
>>> @@ -623,6 +625,7 @@ struct cxl_port {
>>> } cdat;
>>> bool cdat_available;
>>> long pci_latency;
>>> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
>>> };
>>> /**
>>> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
>>> index 2a25d1957ddb..4c1c53c29544 100644
>>> --- a/drivers/cxl/cxlmem.h
>>> +++ b/drivers/cxl/cxlmem.h
>>> @@ -428,6 +428,7 @@ struct cxl_dpa_perf {
>>> * @serial: PCIe Device Serial Number
>>> * @type: Generic Memory Class device or Vendor Specific Memory device
>>> * @cxl_mbox: CXL mailbox context
>>> + * @capabilities: those capabilities as defined in device mapped registers
>>> */
>>> struct cxl_dev_state {
>>> struct device *dev;
>>> @@ -443,6 +444,7 @@ struct cxl_dev_state {
>>> u64 serial;
>>> enum cxl_devtype type;
>>> struct cxl_mailbox cxl_mbox;
>>> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
>>> };
>>> static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
>>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>>> index 0b910ef52db7..528d4ca79fd1 100644
>>> --- a/drivers/cxl/pci.c
>>> +++ b/drivers/cxl/pci.c
>>> @@ -504,7 +504,8 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
>>> }
>>> static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
>>> - struct cxl_register_map *map)
>>> + struct cxl_register_map *map,
>>> + unsigned long *caps)
>>> {
>>> int rc;
>>> @@ -521,7 +522,7 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
>>> if (rc)
>>> return rc;
>>> - return cxl_setup_regs(map);
>>> + return cxl_setup_regs(map, caps);
>>> }
>>> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
>>> @@ -848,7 +849,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>> cxl_set_dvsec(cxlds, dvsec);
>>> - rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>>> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
>>> + cxlds->capabilities);
>>> if (rc)
>>> return rc;
>>> @@ -861,7 +863,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>> * still be useful for management functions so don't return an error.
>>> */
>>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
>>> - &cxlds->reg_map);
>>> + &cxlds->reg_map, cxlds->capabilities);
>>> if (rc)
>>> dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
>>> else if (!cxlds->reg_map.component_map.ras.valid)
>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>> index 19e5d883557a..dcc9ec8a0aec 100644
>>> --- a/include/cxl/cxl.h
>>> +++ b/include/cxl/cxl.h
>>> @@ -12,6 +12,36 @@ enum cxl_resource {
>>> CXL_RES_PMEM,
>>> };
>>> +/* Capabilities as defined for:
>>> + *
>>> + * Component Registers (Table 8-22 CXL 3.1 specification)
>>> + * Device Registers (8.2.8.2.1 CXL 3.1 specification)
>>> + */
>>> +
>>> +enum cxl_dev_cap {
>>> + /* capabilities from Component Registers */
>>> + CXL_DEV_CAP_RAS,
>>> + CXL_DEV_CAP_SEC,
>> There are a few caps that does not seem to be used yet. Should we not bother defining them until they are being used?
>
>
> Jonathan Cameron did suggest it as well, but I think, only when dealing with capabilities discovery and checking.
>
> It is weird to me to mention the specs here and just list a few of the capabilities defined, but I will remove those not used yet if that is the general view.
I think that is perfectly fine not to define them all. In general we want to avoid "dead code" in the kernel if there's no usage yet. When a cap is needed later we can add intentionally. Given this is just enum that is not tied specifically to hardware positions, defining them later on when needed should not impact the current code.
>
>
>>> + CXL_DEV_CAP_LINK,
>>> + CXL_DEV_CAP_HDM,
>>> + CXL_DEV_CAP_SEC_EXT,
>>> + CXL_DEV_CAP_IDE,
>>> + CXL_DEV_CAP_SNOOP_FILTER,
>>> + CXL_DEV_CAP_TIMEOUT_AND_ISOLATION,
>>> + CXL_DEV_CAP_CACHEMEM_EXT,
>>> + CXL_DEV_CAP_BI_ROUTE_TABLE,
>>> + CXL_DEV_CAP_BI_DECODER,
>>> + CXL_DEV_CAP_CACHEID_ROUTE_TABLE,
>>> + CXL_DEV_CAP_CACHEID_DECODER,
>>> + CXL_DEV_CAP_HDM_EXT,
>>> + CXL_DEV_CAP_METADATA_EXT,
>>> + /* capabilities from Device Registers */
>>> + CXL_DEV_CAP_DEV_STATUS,
>>> + CXL_DEV_CAP_MAILBOX_PRIMARY,
>>> + CXL_DEV_CAP_MEMDEV,
>>> + CXL_MAX_CAPS = 32
>> This is changed to 64 in the next patch. Should it just be set to 64 here? I assume you just wanted a bitmap that's u64 long?
>
>
> Oh, yes, I should change it here.
>
> It was suggested to use CXL_MAX_CAPS for clearing/zeroing new allocated bitmaps instead of BITS_PER_TYPE(unsigned long) as in v4, and for that to work, CXL_MAX_CAPS needs to be defined taking into account the size of unsigned long, which is the minimum unit for BITMAP. For x86_64 that is 8 bytes. Otherwise the clearing would leave the upper 32 bits untouched.
>
> Thanks!
>
>
>> DJ
>>
>>> +};
>>> +
>>> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>>> void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-18 16:44 ` [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources alejandro.lucero-palau
@ 2024-11-19 18:00 ` Dave Jiang
2024-11-20 13:44 ` Alejandro Lucero Palau
2024-11-19 19:50 ` Zhi Wang
2024-11-21 2:46 ` Alison Schofield
2 siblings, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-19 18:00 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> For a resource defined with size zero, resource_contains returns
> always true.
>
> Add resource size check before using it.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Should this be broken out and send ahead of the type2 series?
nit below
> ---
> drivers/cxl/core/hdm.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index 223c273c0cd1..c58d6b8f9b58 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> cxled->dpa_res = res;
> cxled->skip = skipped;
>
> - if (resource_contains(&cxlds->pmem_res, res))
> + if (resource_size(&cxlds->pmem_res) &&
> + resource_contains(&cxlds->pmem_res, res)) {
> cxled->mode = CXL_DECODER_PMEM;
> - else if (resource_contains(&cxlds->ram_res, res))
> + } else if (resource_size(&cxlds->ram_res) &&
> + resource_contains(&cxlds->ram_res, res)) {
> cxled->mode = CXL_DECODER_RAM;
> + }
> else {
} else {
> dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
> port->id, cxled->cxld.id, cxled->dpa_res);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 11/27] cxl: add function for setting media ready by a driver
2024-11-18 16:44 ` [PATCH v5 11/27] cxl: add function for setting media ready by a driver alejandro.lucero-palau
@ 2024-11-19 18:12 ` Dave Jiang
2024-11-22 20:45 ` Ben Cheatham
1 sibling, 0 replies; 99+ messages in thread
From: Dave Jiang @ 2024-11-19 18:12 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> A Type-2 driver can require to set the memory availability explicitly.
>
> Add a function to the exported CXL API for accelerator drivers.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/memdev.c | 6 ++++++
> include/cxl/cxl.h | 1 +
> 2 files changed, 7 insertions(+)
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index 7450172c1864..d746c8a1021c 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -795,6 +795,12 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
> }
> EXPORT_SYMBOL_NS_GPL(cxl_release_resource, CXL);
>
> +void cxl_set_media_ready(struct cxl_dev_state *cxlds)
> +{
> + cxlds->media_ready = true;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_media_ready, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index e0bafd066b93..6033ce84b3d3 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -56,4 +56,5 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
> int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
> int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> +void cxl_set_media_ready(struct cxl_dev_state *cxlds);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-18 16:44 ` [PATCH v5 13/27] cxl: prepare memdev creation for type2 alejandro.lucero-palau
@ 2024-11-19 18:24 ` Dave Jiang
2024-11-19 20:06 ` Zhi Wang
2024-11-22 20:45 ` Ben Cheatham
1 sibling, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-19 18:24 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device when
> creating a memdev leading to problems when obtaining cxl_memdev_state
> references from a CXL_DEVTYPE_DEVMEM type. This last device type is
> managed by a specific vendor driver and does not need same sysfs files
> since not userspace intervention is expected.
>
> Create a new cxl_mem device type with no attributes for Type2.
>
> Avoid debugfs files relying on existence of clx_memdev_state.
>
> Make devm_cxl_add_memdev accesible from a accel driver.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/cdat.c | 3 +++
> drivers/cxl/core/memdev.c | 15 +++++++++++++--
> drivers/cxl/core/region.c | 3 ++-
> drivers/cxl/mem.c | 25 +++++++++++++++++++------
> include/cxl/cxl.h | 2 ++
> 5 files changed, 39 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> index e9cd7939c407..192cff18ea25 100644
> --- a/drivers/cxl/core/cdat.c
> +++ b/drivers/cxl/core/cdat.c
> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle
> struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
> struct cxl_dpa_perf *perf;
>
> + if (!mds)
> + return ERR_PTR(-EINVAL);
> +
> switch (mode) {
> case CXL_DECODER_RAM:
> perf = &mds->ram_perf;
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index d746c8a1021c..df31eea0c06b 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -547,9 +547,17 @@ static const struct device_type cxl_memdev_type = {
> .groups = cxl_memdev_attribute_groups,
> };
>
> +static const struct device_type cxl_accel_memdev_type = {
> + .name = "cxl_memdev",
> + .release = cxl_memdev_release,
> + .devnode = cxl_memdev_devnode,
> +};
> +
> bool is_cxl_memdev(const struct device *dev)
> {
> - return dev->type == &cxl_memdev_type;
> + return (dev->type == &cxl_memdev_type ||
> + dev->type == &cxl_accel_memdev_type);
> +
> }
> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
Does type2 device also exports a CDAT?
I'm also wondering if we should have distinctive helpers:
is_cxl_type3_memdev()
is_cxl_type2_memdev()
and is_cxl_memdev() is just calling those two helpers above.
And if no CDAT is exported, we should change the is_cxl_memdev() to is_cxl_type3_memdev() in read_cdat_data().
DJ
>
> @@ -660,7 +668,10 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> dev->parent = cxlds->dev;
> dev->bus = &cxl_bus_type;
> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
> - dev->type = &cxl_memdev_type;
> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
> + dev->type = &cxl_accel_memdev_type;
> + else
> + dev->type = &cxl_memdev_type;
> device_set_pm_not_required(dev);
> INIT_WORK(&cxlmd->detach_work, detach_memdev);
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index dff618c708dc..622e3bb2e04b 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct cxl_region *cxlr,
> return -EINVAL;
> }
>
> - cxl_region_perf_data_calculate(cxlr, cxled);
> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
> + cxl_region_perf_data_calculate(cxlr, cxled);
>
> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
> int i;
> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
> index a9fd5cd5a0d2..cb771bf196cd 100644
> --- a/drivers/cxl/mem.c
> +++ b/drivers/cxl/mem.c
> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
> dentry = cxl_debugfs_create_dir(dev_name(dev));
> debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
>
> - if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
> - debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
> - &cxl_poison_inject_fops);
> - if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
> - debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
> - &cxl_poison_clear_fops);
> + /*
> + * Avoid poison debugfs files for Type2 devices as they rely on
> + * cxl_memdev_state.
> + */
> + if (mds) {
> + if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
> + debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
> + &cxl_poison_inject_fops);
> + if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
> + debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
> + &cxl_poison_clear_fops);
> + }
>
> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
> if (rc)
> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
> struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
> struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
>
> + /*
> + * Avoid poison sysfs files for Type2 devices as they rely on
> + * cxl_memdev_state.
> + */
> + if (!mds)
> + return 0;
> +
> if (a == &dev_attr_trigger_poison_list.attr)
> if (!test_bit(CXL_POISON_ENABLED_LIST,
> mds->poison.enabled_cmds))
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 6033ce84b3d3..5608ed0f5f15 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
> int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> void cxl_set_media_ready(struct cxl_dev_state *cxlds);
> +struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
> + struct cxl_dev_state *cxlds);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-18 16:44 ` [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources alejandro.lucero-palau
2024-11-19 18:00 ` Dave Jiang
@ 2024-11-19 19:50 ` Zhi Wang
2024-11-20 13:45 ` Alejandro Lucero Palau
2024-11-21 2:46 ` Alison Schofield
2 siblings, 1 reply; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 19:50 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:17 +0000
<alejandro.lucero-palau@amd.com> wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> For a resource defined with size zero, resource_contains returns
> always true.
>
> Add resource size check before using it.
>
Does this trigger a bug? Looks like this should be with a Fixes: tag?
Z.
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/hdm.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index 223c273c0cd1..c58d6b8f9b58 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct
> cxl_endpoint_decoder *cxled, cxled->dpa_res = res;
> cxled->skip = skipped;
>
> - if (resource_contains(&cxlds->pmem_res, res))
> + if (resource_size(&cxlds->pmem_res) &&
> + resource_contains(&cxlds->pmem_res, res)) {
> cxled->mode = CXL_DECODER_PMEM;
> - else if (resource_contains(&cxlds->ram_res, res))
> + } else if (resource_size(&cxlds->ram_res) &&
> + resource_contains(&cxlds->ram_res, res)) {
> cxled->mode = CXL_DECODER_RAM;
> + }
> else {
> dev_warn(dev, "decoder%d.%d: %pr mixed mode not
> supported\n", port->id, cxled->cxld.id, cxled->dpa_res);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-19 18:24 ` Dave Jiang
@ 2024-11-19 20:06 ` Zhi Wang
2024-11-19 21:27 ` Dave Jiang
0 siblings, 1 reply; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:06 UTC (permalink / raw)
To: Dave Jiang
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet,
Alejandro Lucero
On Tue, 19 Nov 2024 11:24:44 -0700
Dave Jiang <dave.jiang@intel.com> wrote:
>
>
> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> > From: Alejandro Lucero <alucerop@amd.com>
> >
> > Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device
> > when creating a memdev leading to problems when obtaining
> > cxl_memdev_state references from a CXL_DEVTYPE_DEVMEM type. This
> > last device type is managed by a specific vendor driver and does
> > not need same sysfs files since not userspace intervention is
> > expected.
> >
> > Create a new cxl_mem device type with no attributes for Type2.
> >
> > Avoid debugfs files relying on existence of clx_memdev_state.
> >
> > Make devm_cxl_add_memdev accesible from a accel driver.
> >
> > Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> > ---
> > drivers/cxl/core/cdat.c | 3 +++
> > drivers/cxl/core/memdev.c | 15 +++++++++++++--
> > drivers/cxl/core/region.c | 3 ++-
> > drivers/cxl/mem.c | 25 +++++++++++++++++++------
> > include/cxl/cxl.h | 2 ++
> > 5 files changed, 39 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> > index e9cd7939c407..192cff18ea25 100644
> > --- a/drivers/cxl/core/cdat.c
> > +++ b/drivers/cxl/core/cdat.c
> > @@ -577,6 +577,9 @@ static struct cxl_dpa_perf
> > *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle struct
> > cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct
> > cxl_dpa_perf *perf;
> > + if (!mds)
> > + return ERR_PTR(-EINVAL);
> > +
> > switch (mode) {
> > case CXL_DECODER_RAM:
> > perf = &mds->ram_perf;
> > diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> > index d746c8a1021c..df31eea0c06b 100644
> > --- a/drivers/cxl/core/memdev.c
> > +++ b/drivers/cxl/core/memdev.c
> > @@ -547,9 +547,17 @@ static const struct device_type
> > cxl_memdev_type = { .groups = cxl_memdev_attribute_groups,
> > };
> >
> > +static const struct device_type cxl_accel_memdev_type = {
> > + .name = "cxl_memdev",
> > + .release = cxl_memdev_release,
> > + .devnode = cxl_memdev_devnode,
> > +};
> > +
> > bool is_cxl_memdev(const struct device *dev)
> > {
> > - return dev->type == &cxl_memdev_type;
> > + return (dev->type == &cxl_memdev_type ||
> > + dev->type == &cxl_accel_memdev_type);
> > +
> > }
> > EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
>
> Does type2 device also exports a CDAT?
>
Yes. Type2 can also export a CDAT.
> I'm also wondering if we should have distinctive helpers:
> is_cxl_type3_memdev()
> is_cxl_type2_memdev()
>
> and is_cxl_memdev() is just calling those two helpers above.
>
> And if no CDAT is exported, we should change the is_cxl_memdev() to
> is_cxl_type3_memdev() in read_cdat_data().
>
> DJ
>
> >
> > @@ -660,7 +668,10 @@ static struct cxl_memdev
> > *cxl_memdev_alloc(struct cxl_dev_state *cxlds, dev->parent =
> > cxlds->dev; dev->bus = &cxl_bus_type;
> > dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
> > - dev->type = &cxl_memdev_type;
> > + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
> > + dev->type = &cxl_accel_memdev_type;
> > + else
> > + dev->type = &cxl_memdev_type;
> > device_set_pm_not_required(dev);
> > INIT_WORK(&cxlmd->detach_work, detach_memdev);
> >
> > diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> > index dff618c708dc..622e3bb2e04b 100644
> > --- a/drivers/cxl/core/region.c
> > +++ b/drivers/cxl/core/region.c
> > @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct
> > cxl_region *cxlr, return -EINVAL;
> > }
> >
> > - cxl_region_perf_data_calculate(cxlr, cxled);
> > + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
> > + cxl_region_perf_data_calculate(cxlr, cxled);
> >
> > if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
> > int i;
> > diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
> > index a9fd5cd5a0d2..cb771bf196cd 100644
> > --- a/drivers/cxl/mem.c
> > +++ b/drivers/cxl/mem.c
> > @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
> > dentry = cxl_debugfs_create_dir(dev_name(dev));
> > debugfs_create_devm_seqfile(dev, "dpamem", dentry,
> > cxl_mem_dpa_show);
> > - if (test_bit(CXL_POISON_ENABLED_INJECT,
> > mds->poison.enabled_cmds))
> > - debugfs_create_file("inject_poison", 0200, dentry,
> > cxlmd,
> > - &cxl_poison_inject_fops);
> > - if (test_bit(CXL_POISON_ENABLED_CLEAR,
> > mds->poison.enabled_cmds))
> > - debugfs_create_file("clear_poison", 0200, dentry,
> > cxlmd,
> > - &cxl_poison_clear_fops);
> > + /*
> > + * Avoid poison debugfs files for Type2 devices as they
> > rely on
> > + * cxl_memdev_state.
> > + */
> > + if (mds) {
> > + if (test_bit(CXL_POISON_ENABLED_INJECT,
> > mds->poison.enabled_cmds))
> > + debugfs_create_file("inject_poison", 0200,
> > dentry, cxlmd,
> > +
> > &cxl_poison_inject_fops);
> > + if (test_bit(CXL_POISON_ENABLED_CLEAR,
> > mds->poison.enabled_cmds))
> > + debugfs_create_file("clear_poison", 0200,
> > dentry, cxlmd,
> > +
> > &cxl_poison_clear_fops);
> > + }
> >
> > rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
> > if (rc)
> > @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject
> > *kobj, struct attribute *a, int n) struct cxl_memdev *cxlmd =
> > to_cxl_memdev(dev); struct cxl_memdev_state *mds =
> > to_cxl_memdev_state(cxlmd->cxlds);
> > + /*
> > + * Avoid poison sysfs files for Type2 devices as they rely
> > on
> > + * cxl_memdev_state.
> > + */
> > + if (!mds)
> > + return 0;
> > +
> > if (a == &dev_attr_trigger_poison_list.attr)
> > if (!test_bit(CXL_POISON_ENABLED_LIST,
> > mds->poison.enabled_cmds))
> > diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> > index 6033ce84b3d3..5608ed0f5f15 100644
> > --- a/include/cxl/cxl.h
> > +++ b/include/cxl/cxl.h
> > @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev
> > *pdev, struct cxl_dev_state *cxlds); int
> > cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource
> > type); int cxl_release_resource(struct cxl_dev_state *cxlds, enum
> > cxl_resource type); void cxl_set_media_ready(struct cxl_dev_state
> > *cxlds); +struct cxl_memdev *devm_cxl_add_memdev(struct device
> > *host,
> > + struct cxl_dev_state
> > *cxlds); #endif
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 19/27] cxl: make region type based on endpoint type
2024-11-18 16:44 ` [PATCH v5 19/27] cxl: make region type based on endpoint type alejandro.lucero-palau
@ 2024-11-19 20:16 ` Zhi Wang
2024-11-21 16:16 ` Dave Jiang
1 sibling, 0 replies; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:16 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:26 +0000
<alejandro.lucero-palau@amd.com> wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
LGTM. Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> Current code is expecting Type3 or CXL_DECODER_HOSTONLYMEM devices
> only. Support for Type2 implies region type needs to be based on the
> endpoint type instead.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/region.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index d107cc1b4350..8e2dbd15cfc0 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2654,7 +2654,8 @@ static ssize_t create_ram_region_show(struct
> device *dev, }
>
> static struct cxl_region *__create_region(struct cxl_root_decoder
> *cxlrd,
> - enum cxl_decoder_mode
> mode, int id)
> + enum cxl_decoder_mode
> mode, int id,
> + enum cxl_decoder_type
> target_type) {
> int rc;
>
> @@ -2676,7 +2677,7 @@ static struct cxl_region
> *__create_region(struct cxl_root_decoder *cxlrd, return
> ERR_PTR(-EBUSY); }
>
> - return devm_cxl_add_region(cxlrd, id, mode,
> CXL_DECODER_HOSTONLYMEM);
> + return devm_cxl_add_region(cxlrd, id, mode, target_type);
> }
>
> static ssize_t create_pmem_region_store(struct device *dev,
> @@ -2691,7 +2692,8 @@ static ssize_t create_pmem_region_store(struct
> device *dev, if (rc != 1)
> return -EINVAL;
>
> - cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id);
> + cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id,
> + CXL_DECODER_HOSTONLYMEM);
> if (IS_ERR(cxlr))
> return PTR_ERR(cxlr);
>
> @@ -2711,7 +2713,8 @@ static ssize_t create_ram_region_store(struct
> device *dev, if (rc != 1)
> return -EINVAL;
>
> - cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id);
> + cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id,
> + CXL_DECODER_HOSTONLYMEM);
> if (IS_ERR(cxlr))
> return PTR_ERR(cxlr);
>
> @@ -3372,7 +3375,8 @@ static struct cxl_region
> *construct_region(struct cxl_root_decoder *cxlrd,
> do {
> cxlr = __create_region(cxlrd, cxled->mode,
> -
> atomic_read(&cxlrd->region_id));
> +
> atomic_read(&cxlrd->region_id),
> + cxled->cxld.target_type);
> } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
>
> if (IS_ERR(cxlr)) {
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 20/27] cxl/region: factor out interleave ways setup
2024-11-18 16:44 ` [PATCH v5 20/27] cxl/region: factor out interleave ways setup alejandro.lucero-palau
@ 2024-11-19 20:20 ` Zhi Wang
2024-11-21 16:23 ` Dave Jiang
1 sibling, 0 replies; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:20 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:27 +0000
<alejandro.lucero-palau@amd.com> wrote:
LGTM. Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> From: Alejandro Lucero <alucerop@amd.com>
>
> In preparation for kernel driven region creation, factor out a common
> helper from the user-sysfs region setup for interleave ways.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/cxl/core/region.c | 46
> +++++++++++++++++++++++---------------- 1 file changed, 27
> insertions(+), 19 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 8e2dbd15cfc0..04f82adb763f 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -464,22 +464,14 @@ static ssize_t interleave_ways_show(struct
> device *dev,
> static const struct attribute_group
> *get_cxl_region_target_group(void);
> -static ssize_t interleave_ways_store(struct device *dev,
> - struct device_attribute *attr,
> - const char *buf, size_t len)
> +static int set_interleave_ways(struct cxl_region *cxlr, int val)
> {
> - struct cxl_root_decoder *cxlrd =
> to_cxl_root_decoder(dev->parent);
> + struct cxl_root_decoder *cxlrd =
> to_cxl_root_decoder(cxlr->dev.parent); struct cxl_decoder *cxld =
> &cxlrd->cxlsd.cxld;
> - struct cxl_region *cxlr = to_cxl_region(dev);
> struct cxl_region_params *p = &cxlr->params;
> - unsigned int val, save;
> - int rc;
> + int save, rc;
> u8 iw;
>
> - rc = kstrtouint(buf, 0, &val);
> - if (rc)
> - return rc;
> -
> rc = ways_to_eiw(val, &iw);
> if (rc)
> return rc;
> @@ -494,20 +486,36 @@ static ssize_t interleave_ways_store(struct
> device *dev, return -EINVAL;
> }
>
> - rc = down_write_killable(&cxl_region_rwsem);
> - if (rc)
> - return rc;
> - if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
> - rc = -EBUSY;
> - goto out;
> - }
> + lockdep_assert_held_write(&cxl_region_rwsem);
> + if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
> + return -EBUSY;
>
> save = p->interleave_ways;
> p->interleave_ways = val;
> rc = sysfs_update_group(&cxlr->dev.kobj,
> get_cxl_region_target_group()); if (rc)
> p->interleave_ways = save;
> -out:
> +
> + return rc;
> +}
> +
> +static ssize_t interleave_ways_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct cxl_region *cxlr = to_cxl_region(dev);
> + unsigned int val;
> + int rc;
> +
> + rc = kstrtouint(buf, 0, &val);
> + if (rc)
> + return rc;
> +
> + rc = down_write_killable(&cxl_region_rwsem);
> + if (rc)
> + return rc;
> +
> + rc = set_interleave_ways(cxlr, val);
> up_write(&cxl_region_rwsem);
> if (rc)
> return rc;
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 21/27] cxl/region: factor out interleave granularity setup
2024-11-18 16:44 ` [PATCH v5 21/27] cxl/region: factor out interleave granularity setup alejandro.lucero-palau
@ 2024-11-19 20:23 ` Zhi Wang
2024-11-21 16:24 ` Dave Jiang
1 sibling, 0 replies; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:23 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:28 +0000
<alejandro.lucero-palau@amd.com> wrote:
LGTM. Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> From: Alejandro Lucero <alucerop@amd.com>
>
> In preparation for kernel driven region creation, factor out a common
> helper from the user-sysfs region setup for interleave granularity.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/cxl/core/region.c | 39
> +++++++++++++++++++++++---------------- 1 file changed, 23
> insertions(+), 16 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 04f82adb763f..6652887ea396 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -540,21 +540,14 @@ static ssize_t
> interleave_granularity_show(struct device *dev, return rc;
> }
>
> -static ssize_t interleave_granularity_store(struct device *dev,
> - struct device_attribute
> *attr,
> - const char *buf, size_t
> len) +static int set_interleave_granularity(struct cxl_region *cxlr,
> int val) {
> - struct cxl_root_decoder *cxlrd =
> to_cxl_root_decoder(dev->parent);
> + struct cxl_root_decoder *cxlrd =
> to_cxl_root_decoder(cxlr->dev.parent); struct cxl_decoder *cxld =
> &cxlrd->cxlsd.cxld;
> - struct cxl_region *cxlr = to_cxl_region(dev);
> struct cxl_region_params *p = &cxlr->params;
> - int rc, val;
> + int rc;
> u16 ig;
>
> - rc = kstrtoint(buf, 0, &val);
> - if (rc)
> - return rc;
> -
> rc = granularity_to_eig(val, &ig);
> if (rc)
> return rc;
> @@ -570,16 +563,30 @@ static ssize_t
> interleave_granularity_store(struct device *dev, if
> (cxld->interleave_ways > 1 && val != cxld->interleave_granularity)
> return -EINVAL;
> + lockdep_assert_held_write(&cxl_region_rwsem);
> + if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
> + return -EBUSY;
> +
> + p->interleave_granularity = val;
> + return 0;
> +}
> +
> +static ssize_t interleave_granularity_store(struct device *dev,
> + struct device_attribute
> *attr,
> + const char *buf, size_t
> len) +{
> + struct cxl_region *cxlr = to_cxl_region(dev);
> + int rc, val;
> +
> + rc = kstrtoint(buf, 0, &val);
> + if (rc)
> + return rc;
> +
> rc = down_write_killable(&cxl_region_rwsem);
> if (rc)
> return rc;
> - if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
> - rc = -EBUSY;
> - goto out;
> - }
>
> - p->interleave_granularity = val;
> -out:
> + rc = set_interleave_granularity(cxlr, val);
> up_write(&cxl_region_rwsem);
> if (rc)
> return rc;
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 22/27] cxl: allow region creation by type2 drivers
2024-11-18 16:44 ` [PATCH v5 22/27] cxl: allow region creation by type2 drivers alejandro.lucero-palau
@ 2024-11-19 20:37 ` Zhi Wang
2024-11-20 13:51 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:37 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:29 +0000
<alejandro.lucero-palau@amd.com> wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Creating a CXL region requires userspace intervention through the cxl
> sysfs files. Type2 support should allow accelerator drivers to create
> such cxl region from kernel code.
>
> Adding that functionality and integrating it with current support for
> memory expanders.
>
> Based on https://lore.kernel.org/linux-cxl/168592159835.1948938.1647215579839222774.stgit@dwillia2-xfh.jf.intel.com/
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/cxl/core/region.c | 147 ++++++++++++++++++++++++++++++++++----
> drivers/cxl/cxlmem.h | 2 +
> drivers/cxl/port.c | 5 +-
> include/cxl/cxl.h | 4 ++
> 4 files changed, 142 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 6652887ea396..70549d42c2e3 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2256,6 +2256,18 @@ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled)
> return rc;
> }
>
> +int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled)
> +{
> + int rc;
> +
> + down_write(&cxl_region_rwsem);
> + cxled->mode = CXL_DECODER_DEAD;
> + rc = cxl_region_detach(cxled);
> + up_write(&cxl_region_rwsem);
> + return rc;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_accel_region_detach, CXL);
> +
> void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
> {
> down_write(&cxl_region_rwsem);
> @@ -2770,6 +2782,14 @@ cxl_find_region_by_name(struct cxl_root_decoder *cxlrd, const char *name)
> return to_cxl_region(region_dev);
> }
>
> +static void drop_region(struct cxl_region *cxlr)
> +{
> + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
> + struct cxl_port *port = cxlrd_to_port(cxlrd);
> +
> + devm_release_action(port->uport_dev, unregister_region, cxlr);
> +}
> +
> static ssize_t delete_region_store(struct device *dev,
> struct device_attribute *attr,
> const char *buf, size_t len)
> @@ -3376,17 +3396,18 @@ static int match_region_by_range(struct device *dev, void *data)
> return rc;
> }
>
> -/* Establish an empty region covering the given HPA range */
> -static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled)
> +static void construct_region_end(void)
> +{
> + up_write(&cxl_region_rwsem);
> +}
> +
> +static struct cxl_region *construct_region_begin(struct cxl_root_decoder *cxlrd,
> + struct cxl_endpoint_decoder *cxled)
> {
> struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
> - struct cxl_port *port = cxlrd_to_port(cxlrd);
> - struct range *hpa = &cxled->cxld.hpa_range;
> struct cxl_region_params *p;
> struct cxl_region *cxlr;
> - struct resource *res;
> - int rc;
> + int err;
maybe let's keep the original name "rc".
>
> do {
> cxlr = __create_region(cxlrd, cxled->mode,
> @@ -3395,8 +3416,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
> } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
>
> if (IS_ERR(cxlr)) {
> - dev_err(cxlmd->dev.parent,
> - "%s:%s: %s failed assign region: %ld\n",
> + dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n",
> dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
> __func__, PTR_ERR(cxlr));
> return cxlr;
> @@ -3406,13 +3426,33 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
> p = &cxlr->params;
> if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
> dev_err(cxlmd->dev.parent,
> - "%s:%s: %s autodiscovery interrupted\n",
> + "%s:%s: %s region setup interrupted\n",
> dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
> __func__);
> - rc = -EBUSY;
> - goto err;
> + err = -EBUSY;
> + construct_region_end();
> + drop_region(cxlr);
> + return ERR_PTR(err);
> }
>
> + return cxlr;
> +}
> +
> +/* Establish an empty region covering the given HPA range */
> +static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
> + struct cxl_endpoint_decoder *cxled)
> +{
> + struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
> + struct range *hpa = &cxled->cxld.hpa_range;
> + struct cxl_region_params *p;
> + struct cxl_region *cxlr;
> + struct resource *res;
> + int rc;
> +
> + cxlr = construct_region_begin(cxlrd, cxled);
> + if (IS_ERR(cxlr))
> + return cxlr;
> +
> set_bit(CXL_REGION_F_AUTO, &cxlr->flags);
>
> res = kmalloc(sizeof(*res), GFP_KERNEL);
> @@ -3435,6 +3475,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
> __func__, dev_name(&cxlr->dev));
> }
>
> + p = &cxlr->params;
> p->res = res;
> p->interleave_ways = cxled->cxld.interleave_ways;
> p->interleave_granularity = cxled->cxld.interleave_granularity;
> @@ -3452,15 +3493,91 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
> /* ...to match put_device() in cxl_add_to_region() */
> get_device(&cxlr->dev);
> up_write(&cxl_region_rwsem);
> -
> + construct_region_end();
cxl_region_rwsem seems got up_write() two times. Guess you should remove
it like below since it is now done in construct_region_end().
> return cxlr;
>
> err:
> - up_write(&cxl_region_rwsem);
> - devm_release_action(port->uport_dev, unregister_region, cxlr);
> + construct_region_end();
> + drop_region(cxlr);
> + return ERR_PTR(rc);
> +}
> +
> +static struct cxl_region *
> +__construct_new_region(struct cxl_root_decoder *cxlrd,
> + struct cxl_endpoint_decoder *cxled)
> +{
> + struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
> + struct cxl_region_params *p;
> + struct cxl_region *cxlr;
> + int rc;
> +
> + cxlr = construct_region_begin(cxlrd, cxled);
> + if (IS_ERR(cxlr))
> + return cxlr;
> +
> + rc = set_interleave_ways(cxlr, 1);
> + if (rc)
> + goto err;
> +
> + rc = set_interleave_granularity(cxlr, cxld->interleave_granularity);
> + if (rc)
> + goto err;
> +
> + rc = alloc_hpa(cxlr, resource_size(cxled->dpa_res));
> + if (rc)
> + goto err;
> +
> + down_read(&cxl_dpa_rwsem);
> + rc = cxl_region_attach(cxlr, cxled, 0);
> + up_read(&cxl_dpa_rwsem);
> +
> + if (rc)
> + goto err;
> +
> + rc = cxl_region_decode_commit(cxlr);
> + if (rc)
> + goto err;
> +
> + p = &cxlr->params;
> + p->state = CXL_CONFIG_COMMIT;
> +
> + construct_region_end();
> + return cxlr;
> +err:
> + construct_region_end();
> + drop_region(cxlr);
> return ERR_PTR(rc);
> }
>
> +/**
> + * cxl_create_region - Establish a region given an endpoint decoder
> + * @cxlrd: root decoder to allocate HPA
> + * @cxled: endpoint decoder with reserved DPA capacity
> + *
> + * Returns a fully formed region in the commit state and attached to the
> + * cxl_region driver.
> + */
> +struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> + struct cxl_endpoint_decoder *cxled)
> +{
> + struct cxl_region *cxlr;
> +
> + mutex_lock(&cxlrd->range_lock);
> + cxlr = __construct_new_region(cxlrd, cxled);
> + mutex_unlock(&cxlrd->range_lock);
> +
> + if (IS_ERR(cxlr))
> + return cxlr;
> +
> + if (device_attach(&cxlr->dev) <= 0) {
> + dev_err(&cxlr->dev, "failed to create region\n");
> + drop_region(cxlr);
> + return ERR_PTR(-ENODEV);
> + }
> + return cxlr;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
> +
> int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
> {
> struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 4c1c53c29544..9d874f1cb3bf 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -874,4 +874,6 @@ struct cxl_hdm {
> struct seq_file;
> struct dentry *cxl_debugfs_create_dir(const char *dir);
> void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
> +struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> + struct cxl_endpoint_decoder *cxled);
> #endif /* __CXL_MEM_H__ */
> diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c
> index acf2ac70f343..ec1f0cfb11a5 100644
> --- a/drivers/cxl/port.c
> +++ b/drivers/cxl/port.c
> @@ -33,6 +33,7 @@ static void schedule_detach(void *cxlmd)
> static int discover_region(struct device *dev, void *root)
> {
> struct cxl_endpoint_decoder *cxled;
> + struct cxl_memdev *cxlmd;
> int rc;
>
> if (!is_endpoint_decoder(dev))
> @@ -42,7 +43,9 @@ static int discover_region(struct device *dev, void *root)
> if ((cxled->cxld.flags & CXL_DECODER_F_ENABLE) == 0)
> return 0;
>
> - if (cxled->state != CXL_DECODER_STATE_AUTO)
> + cxlmd = cxled_to_memdev(cxled);
> + if (cxled->state != CXL_DECODER_STATE_AUTO ||
> + cxlmd->cxlds->type == CXL_DEVTYPE_DEVMEM)
> return 0;
>
> /*
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 9b5b5472a86b..d295af4f5f9e 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -72,4 +72,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
> resource_size_t min,
> resource_size_t max);
> int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
> +struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> + struct cxl_endpoint_decoder *cxled);
> +
> +int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax
2024-11-18 16:44 ` [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax alejandro.lucero-palau
@ 2024-11-19 20:39 ` Zhi Wang
2024-11-20 13:55 ` Alejandro Lucero Palau
2024-11-22 20:46 ` Ben Cheatham
1 sibling, 1 reply; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:39 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:31 +0000
<alejandro.lucero-palau@amd.com> wrote:
Minor comment: maybe no_dax would be better than "avoid dax".
> From: Alejandro Lucero <alucerop@amd.com>
>
> By definition a type2 cxl device will use the host managed memory for
> specific functionality, therefore it should not be available to other
> uses. However, a dax interface could be just good enough in some cases.
>
> Add a flag to a cxl region for specifically state to not create a dax
> device. Allow a Type2 driver to set that flag at region creation time.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/region.c | 10 +++++++++-
> drivers/cxl/cxl.h | 3 +++
> drivers/cxl/cxlmem.h | 3 ++-
> include/cxl/cxl.h | 3 ++-
> 4 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 70549d42c2e3..eff3ad788077 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -3558,7 +3558,8 @@ __construct_new_region(struct cxl_root_decoder *cxlrd,
> * cxl_region driver.
> */
> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled)
> + struct cxl_endpoint_decoder *cxled,
> + bool avoid_dax)
> {
> struct cxl_region *cxlr;
>
> @@ -3574,6 +3575,10 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> drop_region(cxlr);
> return ERR_PTR(-ENODEV);
> }
> +
> + if (avoid_dax)
> + set_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags);
> +
> return cxlr;
> }
> EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
> @@ -3713,6 +3718,9 @@ static int cxl_region_probe(struct device *dev)
> case CXL_DECODER_PMEM:
> return devm_cxl_add_pmem_region(cxlr);
> case CXL_DECODER_RAM:
> + if (test_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags))
> + return 0;
> +
> /*
> * The region can not be manged by CXL if any portion of
> * it is already online as 'System RAM'
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 1e0e797b9303..ee3385db5663 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -512,6 +512,9 @@ struct cxl_region_params {
> */
> #define CXL_REGION_F_NEEDS_RESET 1
>
> +/* Allow Type2 drivers to specify if a dax region should not be created. */
> +#define CXL_REGION_F_AVOID_DAX 2
> +
> /**
> * struct cxl_region - CXL region
> * @dev: This region's device
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 9d874f1cb3bf..cc2e2a295f3d 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -875,5 +875,6 @@ struct seq_file;
> struct dentry *cxl_debugfs_create_dir(const char *dir);
> void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled);
> + struct cxl_endpoint_decoder *cxled,
> + bool avoid_dax);
> #endif /* __CXL_MEM_H__ */
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index d295af4f5f9e..2a8ebabfc1dd 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -73,7 +73,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
> resource_size_t max);
> int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled);
> + struct cxl_endpoint_decoder *cxled,
> + bool avoid_dax);
>
> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 26/27] cxl: add function for obtaining params from a region
2024-11-18 16:44 ` [PATCH v5 26/27] cxl: add function for obtaining params from a region alejandro.lucero-palau
@ 2024-11-19 20:40 ` Zhi Wang
2024-11-21 2:56 ` Alison Schofield
2024-11-21 16:31 ` Dave Jiang
2 siblings, 0 replies; 99+ messages in thread
From: Zhi Wang @ 2024-11-19 20:40 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 18 Nov 2024 16:44:33 +0000
<alejandro.lucero-palau@amd.com> wrote:
LGTM. Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> From: Alejandro Lucero <alucerop@amd.com>
>
> A CXL region struct contains the physical address to work with.
>
> Add a function for given a opaque cxl region struct returns the params
> to be used for mapping such memory range.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/region.c | 16 ++++++++++++++++
> drivers/cxl/cxl.h | 2 ++
> include/cxl/cxl.h | 2 ++
> 3 files changed, 20 insertions(+)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index eff3ad788077..fa44a60549f7 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2663,6 +2663,22 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
> return ERR_PTR(rc);
> }
>
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end)
> +{
> + if (!region)
> + return -ENODEV;
> +
> + if (!region->params.res)
> + return -ENOSPC;
> +
> + *start = region->params.res->start;
> + *end = region->params.res->end;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_region_params, CXL);
> +
> static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
> {
> return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index ee3385db5663..7b46d313e581 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -913,6 +913,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
>
> bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
>
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end);
> /*
> * Unit test builds overrides this to __weak, find the 'strong' version
> * of these symbols in tools/testing/cxl/.
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 2a8ebabfc1dd..f14a3f292ad8 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -77,4 +77,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> bool avoid_dax);
>
> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-19 20:06 ` Zhi Wang
@ 2024-11-19 21:27 ` Dave Jiang
2024-11-20 13:57 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-19 21:27 UTC (permalink / raw)
To: Zhi Wang
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet,
Alejandro Lucero
On 11/19/24 1:06 PM, Zhi Wang wrote:
> On Tue, 19 Nov 2024 11:24:44 -0700
> Dave Jiang <dave.jiang@intel.com> wrote:
>
>>
>>
>> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>>> From: Alejandro Lucero <alucerop@amd.com>
>>>
>>> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device
>>> when creating a memdev leading to problems when obtaining
>>> cxl_memdev_state references from a CXL_DEVTYPE_DEVMEM type. This
>>> last device type is managed by a specific vendor driver and does
>>> not need same sysfs files since not userspace intervention is
>>> expected.
>>>
>>> Create a new cxl_mem device type with no attributes for Type2.
>>>
>>> Avoid debugfs files relying on existence of clx_memdev_state.
>>>
>>> Make devm_cxl_add_memdev accesible from a accel driver.
>>>
>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>> ---
>>> drivers/cxl/core/cdat.c | 3 +++
>>> drivers/cxl/core/memdev.c | 15 +++++++++++++--
>>> drivers/cxl/core/region.c | 3 ++-
>>> drivers/cxl/mem.c | 25 +++++++++++++++++++------
>>> include/cxl/cxl.h | 2 ++
>>> 5 files changed, 39 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
>>> index e9cd7939c407..192cff18ea25 100644
>>> --- a/drivers/cxl/core/cdat.c
>>> +++ b/drivers/cxl/core/cdat.c
>>> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf
>>> *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle struct
>>> cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct
>>> cxl_dpa_perf *perf;
>>> + if (!mds)
>>> + return ERR_PTR(-EINVAL);
>>> +
>>> switch (mode) {
>>> case CXL_DECODER_RAM:
>>> perf = &mds->ram_perf;
>>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>>> index d746c8a1021c..df31eea0c06b 100644
>>> --- a/drivers/cxl/core/memdev.c
>>> +++ b/drivers/cxl/core/memdev.c
>>> @@ -547,9 +547,17 @@ static const struct device_type
>>> cxl_memdev_type = { .groups = cxl_memdev_attribute_groups,
>>> };
>>>
>>> +static const struct device_type cxl_accel_memdev_type = {
>>> + .name = "cxl_memdev",
>>> + .release = cxl_memdev_release,
>>> + .devnode = cxl_memdev_devnode,
>>> +};
>>> +
>>> bool is_cxl_memdev(const struct device *dev)
>>> {
>>> - return dev->type == &cxl_memdev_type;
>>> + return (dev->type == &cxl_memdev_type ||
>>> + dev->type == &cxl_accel_memdev_type);
>>> +
>>> }
>>> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
>>
>> Does type2 device also exports a CDAT?
>>
>
> Yes. Type2 can also export a CDAT.
Thanks! Probably should have the split out helpers regardless.
>
>> I'm also wondering if we should have distinctive helpers:
>> is_cxl_type3_memdev()
>> is_cxl_type2_memdev()
>>
>> and is_cxl_memdev() is just calling those two helpers above.
>>
>> And if no CDAT is exported, we should change the is_cxl_memdev() to
>> is_cxl_type3_memdev() in read_cdat_data().
>>
>> DJ
>>
>>>
>>> @@ -660,7 +668,10 @@ static struct cxl_memdev
>>> *cxl_memdev_alloc(struct cxl_dev_state *cxlds, dev->parent =
>>> cxlds->dev; dev->bus = &cxl_bus_type;
>>> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
>>> - dev->type = &cxl_memdev_type;
>>> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
>>> + dev->type = &cxl_accel_memdev_type;
>>> + else
>>> + dev->type = &cxl_memdev_type;
>>> device_set_pm_not_required(dev);
>>> INIT_WORK(&cxlmd->detach_work, detach_memdev);
>>>
>>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>>> index dff618c708dc..622e3bb2e04b 100644
>>> --- a/drivers/cxl/core/region.c
>>> +++ b/drivers/cxl/core/region.c
>>> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct
>>> cxl_region *cxlr, return -EINVAL;
>>> }
>>>
>>> - cxl_region_perf_data_calculate(cxlr, cxled);
>>> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
>>> + cxl_region_perf_data_calculate(cxlr, cxled);
>>>
>>> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
>>> int i;
>>> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
>>> index a9fd5cd5a0d2..cb771bf196cd 100644
>>> --- a/drivers/cxl/mem.c
>>> +++ b/drivers/cxl/mem.c
>>> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
>>> dentry = cxl_debugfs_create_dir(dev_name(dev));
>>> debugfs_create_devm_seqfile(dev, "dpamem", dentry,
>>> cxl_mem_dpa_show);
>>> - if (test_bit(CXL_POISON_ENABLED_INJECT,
>>> mds->poison.enabled_cmds))
>>> - debugfs_create_file("inject_poison", 0200, dentry,
>>> cxlmd,
>>> - &cxl_poison_inject_fops);
>>> - if (test_bit(CXL_POISON_ENABLED_CLEAR,
>>> mds->poison.enabled_cmds))
>>> - debugfs_create_file("clear_poison", 0200, dentry,
>>> cxlmd,
>>> - &cxl_poison_clear_fops);
>>> + /*
>>> + * Avoid poison debugfs files for Type2 devices as they
>>> rely on
>>> + * cxl_memdev_state.
>>> + */
>>> + if (mds) {
>>> + if (test_bit(CXL_POISON_ENABLED_INJECT,
>>> mds->poison.enabled_cmds))
>>> + debugfs_create_file("inject_poison", 0200,
>>> dentry, cxlmd,
>>> +
>>> &cxl_poison_inject_fops);
>>> + if (test_bit(CXL_POISON_ENABLED_CLEAR,
>>> mds->poison.enabled_cmds))
>>> + debugfs_create_file("clear_poison", 0200,
>>> dentry, cxlmd,
>>> +
>>> &cxl_poison_clear_fops);
>>> + }
>>>
>>> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
>>> if (rc)
>>> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject
>>> *kobj, struct attribute *a, int n) struct cxl_memdev *cxlmd =
>>> to_cxl_memdev(dev); struct cxl_memdev_state *mds =
>>> to_cxl_memdev_state(cxlmd->cxlds);
>>> + /*
>>> + * Avoid poison sysfs files for Type2 devices as they rely
>>> on
>>> + * cxl_memdev_state.
>>> + */
>>> + if (!mds)
>>> + return 0;
>>> +
>>> if (a == &dev_attr_trigger_poison_list.attr)
>>> if (!test_bit(CXL_POISON_ENABLED_LIST,
>>> mds->poison.enabled_cmds))
>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>> index 6033ce84b3d3..5608ed0f5f15 100644
>>> --- a/include/cxl/cxl.h
>>> +++ b/include/cxl/cxl.h
>>> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev
>>> *pdev, struct cxl_dev_state *cxlds); int
>>> cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource
>>> type); int cxl_release_resource(struct cxl_dev_state *cxlds, enum
>>> cxl_resource type); void cxl_set_media_ready(struct cxl_dev_state
>>> *cxlds); +struct cxl_memdev *devm_cxl_add_memdev(struct device
>>> *host,
>>> + struct cxl_dev_state
>>> *cxlds); #endif
>>
>>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-18 21:55 ` Dave Jiang
@ 2024-11-20 13:40 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:40 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On 11/18/24 21:55, Dave Jiang wrote:
>
> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Differentiate Type3, aka memory expanders, from Type2, aka device
>> accelerators, with a new function for initializing cxl_dev_state.
> Please consider:
> Differentiate CXL memory expanders (type 3) from CXL device
> accelerators (type 2) with a new ...
I'll do.
>> Create accessors to cxl_dev_state to be used by accel drivers.
>>
>> Based on previous work by Dan Williams [1]
>>
>> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Thanks!
>> ---
>> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
>> drivers/cxl/core/pci.c | 1 +
>> drivers/cxl/cxlpci.h | 16 ------------
>> drivers/cxl/pci.c | 13 +++++++---
>> include/cxl/cxl.h | 21 ++++++++++++++++
>> include/cxl/pci.h | 23 ++++++++++++++++++
>> 6 files changed, 105 insertions(+), 20 deletions(-)
>> create mode 100644 include/cxl/cxl.h
>> create mode 100644 include/cxl/pci.h
>>
>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>> index 84fefb76dafa..d083fd13a6dd 100644
>> --- a/drivers/cxl/core/memdev.c
>> +++ b/drivers/cxl/core/memdev.c
>> @@ -1,6 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2020 Intel Corporation. */
>>
>> +#include <cxl/cxl.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/firmware.h>
>> #include <linux/device.h>
>> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>>
>> static struct lock_class_key cxl_memdev_key;
>>
>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
>> +{
>> + struct cxl_dev_state *cxlds;
>> +
>> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
>> + if (!cxlds)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + cxlds->dev = dev;
>> + cxlds->type = CXL_DEVTYPE_DEVMEM;
>> +
>> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
>> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
>> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
>> +
>> + return cxlds;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
>> +
>> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
>> const struct file_operations *fops)
>> {
>> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
>> return 0;
>> }
>>
>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
>> +{
>> + cxlds->cxl_dvsec = dvsec;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
>> +
>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
>> +{
>> + cxlds->serial = serial;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
>> +
>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> + enum cxl_resource type)
>> +{
>> + switch (type) {
>> + case CXL_RES_DPA:
>> + cxlds->dpa_res = res;
>> + return 0;
>> + case CXL_RES_RAM:
>> + cxlds->ram_res = res;
>> + return 0;
>> + case CXL_RES_PMEM:
>> + cxlds->pmem_res = res;
>> + return 0;
>> + }
>> +
>> + return -EINVAL;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
>> +
>> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
>> {
>> struct cxl_memdev *cxlmd =
>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
>> index 420e4be85a1f..ff266e91ea71 100644
>> --- a/drivers/cxl/core/pci.c
>> +++ b/drivers/cxl/core/pci.c
>> @@ -1,5 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
>> +#include <cxl/pci.h>
>> #include <linux/units.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/device.h>
>> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
>> index 4da07727ab9c..eb59019fe5f3 100644
>> --- a/drivers/cxl/cxlpci.h
>> +++ b/drivers/cxl/cxlpci.h
>> @@ -14,22 +14,6 @@
>> */
>> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>>
>> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>> -#define CXL_DVSEC_PCIE_DEVICE 0
>> -#define CXL_DVSEC_CAP_OFFSET 0xA
>> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>> -#define CXL_DVSEC_CTRL_OFFSET 0xC
>> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
>> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
>> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
>> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
>> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
>> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>> -
>> #define CXL_DVSEC_RANGE_MAX 2
>>
>> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>> index 188412d45e0d..0b910ef52db7 100644
>> --- a/drivers/cxl/pci.c
>> +++ b/drivers/cxl/pci.c
>> @@ -1,5 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>> +#include <cxl/cxl.h>
>> +#include <cxl/pci.h>
>> #include <linux/unaligned.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/moduleparam.h>
>> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> struct cxl_memdev *cxlmd;
>> int i, rc, pmu_count;
>> bool irq_avail;
>> + u16 dvsec;
>>
>> /*
>> * Double check the anonymous union trickery in struct cxl_regs
>> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> pci_set_drvdata(pdev, cxlds);
>>
>> cxlds->rcd = is_cxl_restricted(pdev);
>> - cxlds->serial = pci_get_dsn(pdev);
>> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
>> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
>> - if (!cxlds->cxl_dvsec)
>> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
>> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
>> + CXL_DVSEC_PCIE_DEVICE);
>> + if (!dvsec)
>> dev_warn(&pdev->dev,
>> "Device DVSEC not present, skip CXL.mem init\n");
>>
>> + cxl_set_dvsec(cxlds, dvsec);
>> +
>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>> if (rc)
>> return rc;
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> new file mode 100644
>> index 000000000000..19e5d883557a
>> --- /dev/null
>> +++ b/include/cxl/cxl.h
>> @@ -0,0 +1,21 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
>> +
>> +#ifndef __CXL_H
>> +#define __CXL_H
>> +
>> +#include <linux/ioport.h>
>> +
>> +enum cxl_resource {
>> + CXL_RES_DPA,
>> + CXL_RES_RAM,
>> + CXL_RES_PMEM,
>> +};
>> +
>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>> +
>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> + enum cxl_resource);
>> +#endif
>> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
>> new file mode 100644
>> index 000000000000..ad63560caa2c
>> --- /dev/null
>> +++ b/include/cxl/pci.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>> +
>> +#ifndef __CXL_ACCEL_PCI_H
>> +#define __CXL_ACCEL_PCI_H
>> +
>> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>> +#define CXL_DVSEC_PCIE_DEVICE 0
>> +#define CXL_DVSEC_CAP_OFFSET 0xA
>> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>> +#define CXL_DVSEC_CTRL_OFFSET 0xC
>> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
>> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
>> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
>> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
>> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
>> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>> +
>> +#endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port
2024-11-19 15:53 ` Dave Jiang
@ 2024-11-20 13:41 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:41 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On 11/19/24 15:53, Dave Jiang wrote:
>
> On 11/19/24 5:28 AM, Alejandro Lucero Palau wrote:
>> On 11/18/24 22:52, Dave Jiang wrote:
>>> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>>>> From: Alejandro Lucero <alucerop@amd.com>
>>>>
>>>> Type2 devices have some Type3 functionalities as optional like an mbox
>>>> or an hdm decoder, and CXL core needs a way to know what an CXL accelerator
>>>> implements.
>>>>
>>>> Add a new field to cxl_dev_state for keeping device capabilities as discovered
>>>> during initialization. Add same field to cxl_port as registers discovery
>>>> is also used during port initialization.
>>>>
>>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>>> ---
>>>> drivers/cxl/core/port.c | 11 +++++++----
>>>> drivers/cxl/core/regs.c | 21 ++++++++++++++-------
>>>> drivers/cxl/cxl.h | 9 ++++++---
>>>> drivers/cxl/cxlmem.h | 2 ++
>>>> drivers/cxl/pci.c | 10 ++++++----
>>>> include/cxl/cxl.h | 30 ++++++++++++++++++++++++++++++
>>>> 6 files changed, 65 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
>>>> index af92c67bc954..5bc8490a199c 100644
>>>> --- a/drivers/cxl/core/port.c
>>>> +++ b/drivers/cxl/core/port.c
>>>> @@ -749,7 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
>>>> }
>>>> static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map,
>>>> - resource_size_t component_reg_phys)
>>>> + resource_size_t component_reg_phys, unsigned long *caps)
>>>> {
>>>> *map = (struct cxl_register_map) {
>>>> .host = host,
>>>> @@ -763,7 +763,7 @@ static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map
>>>> map->reg_type = CXL_REGLOC_RBI_COMPONENT;
>>>> map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
>>>> - return cxl_setup_regs(map);
>>>> + return cxl_setup_regs(map, caps);
>>>> }
>>>> static int cxl_port_setup_regs(struct cxl_port *port,
>>>> @@ -772,7 +772,7 @@ static int cxl_port_setup_regs(struct cxl_port *port,
>>>> if (dev_is_platform(port->uport_dev))
>>>> return 0;
>>>> return cxl_setup_comp_regs(&port->dev, &port->reg_map,
>>>> - component_reg_phys);
>>>> + component_reg_phys, port->capabilities);
>>>> }
>>>> static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
>>>> @@ -789,7 +789,8 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
>>>> * NULL.
>>>> */
>>>> rc = cxl_setup_comp_regs(dport->dport_dev, &dport->reg_map,
>>>> - component_reg_phys);
>>>> + component_reg_phys,
>>>> + dport->port->capabilities);
>>>> dport->reg_map.host = host;
>>>> return rc;
>>>> }
>>>> @@ -851,6 +852,8 @@ static int cxl_port_add(struct cxl_port *port,
>>>> port->reg_map = cxlds->reg_map;
>>>> port->reg_map.host = &port->dev;
>>>> cxlmd->endpoint = port;
>>>> + bitmap_copy(port->capabilities, cxlds->capabilities,
>>>> + CXL_MAX_CAPS);
>>>> } else if (parent_dport) {
>>>> rc = dev_set_name(dev, "port%d", port->id);
>>>> if (rc)
>>>> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
>>>> index e1082e749c69..8287ec45b018 100644
>>>> --- a/drivers/cxl/core/regs.c
>>>> +++ b/drivers/cxl/core/regs.c
>>>> @@ -4,6 +4,7 @@
>>>> #include <linux/device.h>
>>>> #include <linux/slab.h>
>>>> #include <linux/pci.h>
>>>> +#include <cxl/cxl.h>
>>>> #include <cxlmem.h>
>>>> #include <cxlpci.h>
>>>> #include <pmu.h>
>>>> @@ -36,7 +37,8 @@
>>>> * Probe for component register information and return it in map object.
>>>> */
>>>> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>>> - struct cxl_component_reg_map *map)
>>>> + struct cxl_component_reg_map *map,
>>>> + unsigned long *caps)
>>>> {
>>>> int cap, cap_count;
>>>> u32 cap_array;
>>>> @@ -84,6 +86,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>>> decoder_cnt = cxl_hdm_decoder_count(hdr);
>>>> length = 0x20 * decoder_cnt + 0x10;
>>>> rmap = &map->hdm_decoder;
>>>> + *caps |= BIT(CXL_DEV_CAP_HDM);
>>>> break;
>>>> }
>>>> case CXL_CM_CAP_CAP_ID_RAS:
>>>> @@ -91,6 +94,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>>> offset);
>>>> length = CXL_RAS_CAPABILITY_LENGTH;
>>>> rmap = &map->ras;
>>>> + *caps |= BIT(CXL_DEV_CAP_RAS);
>>>> break;
>>>> default:
>>>> dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
>>>> @@ -117,7 +121,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);
>>>> * Probe for device register information and return it in map object.
>>>> */
>>>> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>>> - struct cxl_device_reg_map *map)
>>>> + struct cxl_device_reg_map *map, unsigned long *caps)
>>>> {
>>>> int cap, cap_count;
>>>> u64 cap_array;
>>>> @@ -146,10 +150,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>>> case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
>>>> dev_dbg(dev, "found Status capability (0x%x)\n", offset);
>>>> rmap = &map->status;
>>>> + *caps |= BIT(CXL_DEV_CAP_DEV_STATUS);
>>>> break;
>>>> case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
>>>> dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
>>>> rmap = &map->mbox;
>>>> + *caps |= BIT(CXL_DEV_CAP_MAILBOX_PRIMARY);
>>>> break;
>>>> case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
>>>> dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
>>>> @@ -157,6 +163,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>>> case CXLDEV_CAP_CAP_ID_MEMDEV:
>>>> dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
>>>> rmap = &map->memdev;
>>>> + *caps |= BIT(CXL_DEV_CAP_MEMDEV);
>>>> break;
>>>> default:
>>>> if (cap_id >= 0x8000)
>>>> @@ -421,7 +428,7 @@ static void cxl_unmap_regblock(struct cxl_register_map *map)
>>>> map->base = NULL;
>>>> }
>>>> -static int cxl_probe_regs(struct cxl_register_map *map)
>>>> +static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
>>>> {
>>>> struct cxl_component_reg_map *comp_map;
>>>> struct cxl_device_reg_map *dev_map;
>>>> @@ -431,12 +438,12 @@ static int cxl_probe_regs(struct cxl_register_map *map)
>>>> switch (map->reg_type) {
>>>> case CXL_REGLOC_RBI_COMPONENT:
>>>> comp_map = &map->component_map;
>>>> - cxl_probe_component_regs(host, base, comp_map);
>>>> + cxl_probe_component_regs(host, base, comp_map, caps);
>>>> dev_dbg(host, "Set up component registers\n");
>>>> break;
>>>> case CXL_REGLOC_RBI_MEMDEV:
>>>> dev_map = &map->device_map;
>>>> - cxl_probe_device_regs(host, base, dev_map);
>>>> + cxl_probe_device_regs(host, base, dev_map, caps);
>>>> if (!dev_map->status.valid || !dev_map->mbox.valid ||
>>>> !dev_map->memdev.valid) {
>>>> dev_err(host, "registers not found: %s%s%s\n",
>>>> @@ -455,7 +462,7 @@ static int cxl_probe_regs(struct cxl_register_map *map)
>>>> return 0;
>>>> }
>>>> -int cxl_setup_regs(struct cxl_register_map *map)
>>>> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps)
>>>> {
>>>> int rc;
>>>> @@ -463,7 +470,7 @@ int cxl_setup_regs(struct cxl_register_map *map)
>>>> if (rc)
>>>> return rc;
>>>> - rc = cxl_probe_regs(map);
>>>> + rc = cxl_probe_regs(map, caps);
>>>> cxl_unmap_regblock(map);
>>>> return rc;
>>>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>>>> index a2be05fd7aa2..e5f918be6fe4 100644
>>>> --- a/drivers/cxl/cxl.h
>>>> +++ b/drivers/cxl/cxl.h
>>>> @@ -4,6 +4,7 @@
>>>> #ifndef __CXL_H__
>>>> #define __CXL_H__
>>>> +#include <cxl/cxl.h>
>>>> #include <linux/libnvdimm.h>
>>>> #include <linux/bitfield.h>
>>>> #include <linux/notifier.h>
>>>> @@ -284,9 +285,9 @@ struct cxl_register_map {
>>>> };
>>>> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
>>>> - struct cxl_component_reg_map *map);
>>>> + struct cxl_component_reg_map *map, unsigned long *caps);
>>>> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
>>>> - struct cxl_device_reg_map *map);
>>>> + struct cxl_device_reg_map *map, unsigned long *caps);
>>>> int cxl_map_component_regs(const struct cxl_register_map *map,
>>>> struct cxl_component_regs *regs,
>>>> unsigned long map_mask);
>>>> @@ -300,7 +301,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
>>>> struct cxl_register_map *map, int index);
>>>> int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
>>>> struct cxl_register_map *map);
>>>> -int cxl_setup_regs(struct cxl_register_map *map);
>>>> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps);
>>>> struct cxl_dport;
>>>> resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
>>>> struct cxl_dport *dport);
>>>> @@ -600,6 +601,7 @@ struct cxl_dax_region {
>>>> * @cdat: Cached CDAT data
>>>> * @cdat_available: Should a CDAT attribute be available in sysfs
>>>> * @pci_latency: Upstream latency in picoseconds
>>>> + * @capabilities: those capabilities as defined in device mapped registers
>>>> */
>>>> struct cxl_port {
>>>> struct device dev;
>>>> @@ -623,6 +625,7 @@ struct cxl_port {
>>>> } cdat;
>>>> bool cdat_available;
>>>> long pci_latency;
>>>> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
>>>> };
>>>> /**
>>>> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
>>>> index 2a25d1957ddb..4c1c53c29544 100644
>>>> --- a/drivers/cxl/cxlmem.h
>>>> +++ b/drivers/cxl/cxlmem.h
>>>> @@ -428,6 +428,7 @@ struct cxl_dpa_perf {
>>>> * @serial: PCIe Device Serial Number
>>>> * @type: Generic Memory Class device or Vendor Specific Memory device
>>>> * @cxl_mbox: CXL mailbox context
>>>> + * @capabilities: those capabilities as defined in device mapped registers
>>>> */
>>>> struct cxl_dev_state {
>>>> struct device *dev;
>>>> @@ -443,6 +444,7 @@ struct cxl_dev_state {
>>>> u64 serial;
>>>> enum cxl_devtype type;
>>>> struct cxl_mailbox cxl_mbox;
>>>> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
>>>> };
>>>> static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
>>>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>>>> index 0b910ef52db7..528d4ca79fd1 100644
>>>> --- a/drivers/cxl/pci.c
>>>> +++ b/drivers/cxl/pci.c
>>>> @@ -504,7 +504,8 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
>>>> }
>>>> static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
>>>> - struct cxl_register_map *map)
>>>> + struct cxl_register_map *map,
>>>> + unsigned long *caps)
>>>> {
>>>> int rc;
>>>> @@ -521,7 +522,7 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
>>>> if (rc)
>>>> return rc;
>>>> - return cxl_setup_regs(map);
>>>> + return cxl_setup_regs(map, caps);
>>>> }
>>>> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
>>>> @@ -848,7 +849,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>>> cxl_set_dvsec(cxlds, dvsec);
>>>> - rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>>>> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
>>>> + cxlds->capabilities);
>>>> if (rc)
>>>> return rc;
>>>> @@ -861,7 +863,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>>> * still be useful for management functions so don't return an error.
>>>> */
>>>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
>>>> - &cxlds->reg_map);
>>>> + &cxlds->reg_map, cxlds->capabilities);
>>>> if (rc)
>>>> dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
>>>> else if (!cxlds->reg_map.component_map.ras.valid)
>>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>>> index 19e5d883557a..dcc9ec8a0aec 100644
>>>> --- a/include/cxl/cxl.h
>>>> +++ b/include/cxl/cxl.h
>>>> @@ -12,6 +12,36 @@ enum cxl_resource {
>>>> CXL_RES_PMEM,
>>>> };
>>>> +/* Capabilities as defined for:
>>>> + *
>>>> + * Component Registers (Table 8-22 CXL 3.1 specification)
>>>> + * Device Registers (8.2.8.2.1 CXL 3.1 specification)
>>>> + */
>>>> +
>>>> +enum cxl_dev_cap {
>>>> + /* capabilities from Component Registers */
>>>> + CXL_DEV_CAP_RAS,
>>>> + CXL_DEV_CAP_SEC,
>>> There are a few caps that does not seem to be used yet. Should we not bother defining them until they are being used?
>>
>> Jonathan Cameron did suggest it as well, but I think, only when dealing with capabilities discovery and checking.
>>
>> It is weird to me to mention the specs here and just list a few of the capabilities defined, but I will remove those not used yet if that is the general view.
> I think that is perfectly fine not to define them all. In general we want to avoid "dead code" in the kernel if there's no usage yet. When a cap is needed later we can add intentionally. Given this is just enum that is not tied specifically to hardware positions, defining them later on when needed should not impact the current code.
OK. I'll remove those not used yet in v6.
Thanks
>>
>>>> + CXL_DEV_CAP_LINK,
>>>> + CXL_DEV_CAP_HDM,
>>>> + CXL_DEV_CAP_SEC_EXT,
>>>> + CXL_DEV_CAP_IDE,
>>>> + CXL_DEV_CAP_SNOOP_FILTER,
>>>> + CXL_DEV_CAP_TIMEOUT_AND_ISOLATION,
>>>> + CXL_DEV_CAP_CACHEMEM_EXT,
>>>> + CXL_DEV_CAP_BI_ROUTE_TABLE,
>>>> + CXL_DEV_CAP_BI_DECODER,
>>>> + CXL_DEV_CAP_CACHEID_ROUTE_TABLE,
>>>> + CXL_DEV_CAP_CACHEID_DECODER,
>>>> + CXL_DEV_CAP_HDM_EXT,
>>>> + CXL_DEV_CAP_METADATA_EXT,
>>>> + /* capabilities from Device Registers */
>>>> + CXL_DEV_CAP_DEV_STATUS,
>>>> + CXL_DEV_CAP_MAILBOX_PRIMARY,
>>>> + CXL_DEV_CAP_MEMDEV,
>>>> + CXL_MAX_CAPS = 32
>>> This is changed to 64 in the next patch. Should it just be set to 64 here? I assume you just wanted a bitmap that's u64 long?
>>
>> Oh, yes, I should change it here.
>>
>> It was suggested to use CXL_MAX_CAPS for clearing/zeroing new allocated bitmaps instead of BITS_PER_TYPE(unsigned long) as in v4, and for that to work, CXL_MAX_CAPS needs to be defined taking into account the size of unsigned long, which is the minimum unit for BITMAP. For x86_64 that is 8 bytes. Otherwise the clearing would leave the upper 32 bits untouched.
>>
>> Thanks!
>>
>>
>>> DJ
>>>
>>>> +};
>>>> +
>>>> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>>>> void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-19 18:00 ` Dave Jiang
@ 2024-11-20 13:44 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:44 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On 11/19/24 18:00, Dave Jiang wrote:
>
> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> For a resource defined with size zero, resource_contains returns
>> always true.
>>
>> Add resource size check before using it.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
>
> Should this be broken out and send ahead of the type2 series?
I could. This seems not a problem though until the new code coming along.
> nit below
>
>> ---
>> drivers/cxl/core/hdm.c | 7 +++++--
>> 1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>> index 223c273c0cd1..c58d6b8f9b58 100644
>> --- a/drivers/cxl/core/hdm.c
>> +++ b/drivers/cxl/core/hdm.c
>> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
>> cxled->dpa_res = res;
>> cxled->skip = skipped;
>>
>> - if (resource_contains(&cxlds->pmem_res, res))
>> + if (resource_size(&cxlds->pmem_res) &&
>> + resource_contains(&cxlds->pmem_res, res)) {
>> cxled->mode = CXL_DECODER_PMEM;
>> - else if (resource_contains(&cxlds->ram_res, res))
>> + } else if (resource_size(&cxlds->ram_res) &&
>> + resource_contains(&cxlds->ram_res, res)) {
>> cxled->mode = CXL_DECODER_RAM;
>> + }
>> else {
> } else {
I'll fix it.
Thanks!
>> dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
>> port->id, cxled->cxld.id, cxled->dpa_res);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-19 19:50 ` Zhi Wang
@ 2024-11-20 13:45 ` Alejandro Lucero Palau
2024-11-21 7:13 ` Zhi Wang
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:45 UTC (permalink / raw)
To: Zhi Wang, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/19/24 19:50, Zhi Wang wrote:
> On Mon, 18 Nov 2024 16:44:17 +0000
> <alejandro.lucero-palau@amd.com> wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> For a resource defined with size zero, resource_contains returns
>> always true.
>>
>> Add resource size check before using it.
>>
> Does this trigger a bug? Looks like this should be with a Fixes: tag?
It seems it does not until the new code for type2 support.
> Z.
>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/hdm.c | 7 +++++--
>> 1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>> index 223c273c0cd1..c58d6b8f9b58 100644
>> --- a/drivers/cxl/core/hdm.c
>> +++ b/drivers/cxl/core/hdm.c
>> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct
>> cxl_endpoint_decoder *cxled, cxled->dpa_res = res;
>> cxled->skip = skipped;
>>
>> - if (resource_contains(&cxlds->pmem_res, res))
>> + if (resource_size(&cxlds->pmem_res) &&
>> + resource_contains(&cxlds->pmem_res, res)) {
>> cxled->mode = CXL_DECODER_PMEM;
>> - else if (resource_contains(&cxlds->ram_res, res))
>> + } else if (resource_size(&cxlds->ram_res) &&
>> + resource_contains(&cxlds->ram_res, res)) {
>> cxled->mode = CXL_DECODER_RAM;
>> + }
>> else {
>> dev_warn(dev, "decoder%d.%d: %pr mixed mode not
>> supported\n", port->id, cxled->cxld.id, cxled->dpa_res);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 22/27] cxl: allow region creation by type2 drivers
2024-11-19 20:37 ` Zhi Wang
@ 2024-11-20 13:51 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:51 UTC (permalink / raw)
To: Zhi Wang, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/19/24 20:37, Zhi Wang wrote:
> On Mon, 18 Nov 2024 16:44:29 +0000
> <alejandro.lucero-palau@amd.com> wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
<snip>
>>
>> -/* Establish an empty region covering the given HPA range */
>> -static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled)
>> +static void construct_region_end(void)
>> +{
>> + up_write(&cxl_region_rwsem);
>> +}
>> +
>> +static struct cxl_region *construct_region_begin(struct cxl_root_decoder *cxlrd,
>> + struct cxl_endpoint_decoder *cxled)
>> {
>> struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
>> - struct cxl_port *port = cxlrd_to_port(cxlrd);
>> - struct range *hpa = &cxled->cxld.hpa_range;
>> struct cxl_region_params *p;
>> struct cxl_region *cxlr;
>> - struct resource *res;
>> - int rc;
>> + int err;
> maybe let's keep the original name "rc".
Note this is a new function. It comes straight from original Dan's
patch, and I think he changed that as there is another function doing
the "return call" which invokes this one as part of the call.
>>
>> do {
>> cxlr = __create_region(cxlrd, cxled->mode,
>> @@ -3395,8 +3416,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>> } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
>>
>> if (IS_ERR(cxlr)) {
>> - dev_err(cxlmd->dev.parent,
>> - "%s:%s: %s failed assign region: %ld\n",
>> + dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n",
>> dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
>> __func__, PTR_ERR(cxlr));
>> return cxlr;
>> @@ -3406,13 +3426,33 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>> p = &cxlr->params;
>> if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
>> dev_err(cxlmd->dev.parent,
>> - "%s:%s: %s autodiscovery interrupted\n",
>> + "%s:%s: %s region setup interrupted\n",
>> dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
>> __func__);
>> - rc = -EBUSY;
>> - goto err;
>> + err = -EBUSY;
>> + construct_region_end();
>> + drop_region(cxlr);
>> + return ERR_PTR(err);
>> }
>>
>> + return cxlr;
>> +}
>> +
>> +/* Establish an empty region covering the given HPA range */
>> +static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>> + struct cxl_endpoint_decoder *cxled)
>> +{
>> + struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
>> + struct range *hpa = &cxled->cxld.hpa_range;
>> + struct cxl_region_params *p;
>> + struct cxl_region *cxlr;
>> + struct resource *res;
>> + int rc;
>> +
>> + cxlr = construct_region_begin(cxlrd, cxled);
>> + if (IS_ERR(cxlr))
>> + return cxlr;
>> +
>> set_bit(CXL_REGION_F_AUTO, &cxlr->flags);
>>
>> res = kmalloc(sizeof(*res), GFP_KERNEL);
>> @@ -3435,6 +3475,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>> __func__, dev_name(&cxlr->dev));
>> }
>>
>> + p = &cxlr->params;
>> p->res = res;
>> p->interleave_ways = cxled->cxld.interleave_ways;
>> p->interleave_granularity = cxled->cxld.interleave_granularity;
>> @@ -3452,15 +3493,91 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>> /* ...to match put_device() in cxl_add_to_region() */
>> get_device(&cxlr->dev);
>> up_write(&cxl_region_rwsem);
>> -
>> + construct_region_end();
> cxl_region_rwsem seems got up_write() two times. Guess you should remove
> it like below since it is now done in construct_region_end().
You are right. I think I messed up that with the code below for handling
a potential error.
I'll fix it.
Good catch!
>> return cxlr;
>>
>> err:
>> - up_write(&cxl_region_rwsem);
>> - devm_release_action(port->uport_dev, unregister_region, cxlr);
>> + construct_region_end();
>> + drop_region(cxlr);
>> + return ERR_PTR(rc);
>> +}
>> +
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax
2024-11-19 20:39 ` Zhi Wang
@ 2024-11-20 13:55 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:55 UTC (permalink / raw)
To: Zhi Wang, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/19/24 20:39, Zhi Wang wrote:
> On Mon, 18 Nov 2024 16:44:31 +0000
> <alejandro.lucero-palau@amd.com> wrote:
>
> Minor comment: maybe no_dax would be better than "avoid dax".
It makes sense.
I'll do the change.
Thanks
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> By definition a type2 cxl device will use the host managed memory for
>> specific functionality, therefore it should not be available to other
>> uses. However, a dax interface could be just good enough in some cases.
>>
>> Add a flag to a cxl region for specifically state to not create a dax
>> device. Allow a Type2 driver to set that flag at region creation time.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/region.c | 10 +++++++++-
>> drivers/cxl/cxl.h | 3 +++
>> drivers/cxl/cxlmem.h | 3 ++-
>> include/cxl/cxl.h | 3 ++-
>> 4 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index 70549d42c2e3..eff3ad788077 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -3558,7 +3558,8 @@ __construct_new_region(struct cxl_root_decoder *cxlrd,
>> * cxl_region driver.
>> */
>> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled)
>> + struct cxl_endpoint_decoder *cxled,
>> + bool avoid_dax)
>> {
>> struct cxl_region *cxlr;
>>
>> @@ -3574,6 +3575,10 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> drop_region(cxlr);
>> return ERR_PTR(-ENODEV);
>> }
>> +
>> + if (avoid_dax)
>> + set_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags);
>> +
>> return cxlr;
>> }
>> EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
>> @@ -3713,6 +3718,9 @@ static int cxl_region_probe(struct device *dev)
>> case CXL_DECODER_PMEM:
>> return devm_cxl_add_pmem_region(cxlr);
>> case CXL_DECODER_RAM:
>> + if (test_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags))
>> + return 0;
>> +
>> /*
>> * The region can not be manged by CXL if any portion of
>> * it is already online as 'System RAM'
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index 1e0e797b9303..ee3385db5663 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -512,6 +512,9 @@ struct cxl_region_params {
>> */
>> #define CXL_REGION_F_NEEDS_RESET 1
>>
>> +/* Allow Type2 drivers to specify if a dax region should not be created. */
>> +#define CXL_REGION_F_AVOID_DAX 2
>> +
>> /**
>> * struct cxl_region - CXL region
>> * @dev: This region's device
>> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
>> index 9d874f1cb3bf..cc2e2a295f3d 100644
>> --- a/drivers/cxl/cxlmem.h
>> +++ b/drivers/cxl/cxlmem.h
>> @@ -875,5 +875,6 @@ struct seq_file;
>> struct dentry *cxl_debugfs_create_dir(const char *dir);
>> void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
>> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled);
>> + struct cxl_endpoint_decoder *cxled,
>> + bool avoid_dax);
>> #endif /* __CXL_MEM_H__ */
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index d295af4f5f9e..2a8ebabfc1dd 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -73,7 +73,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
>> resource_size_t max);
>> int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
>> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled);
>> + struct cxl_endpoint_decoder *cxled,
>> + bool avoid_dax);
>>
>> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-19 21:27 ` Dave Jiang
@ 2024-11-20 13:57 ` Alejandro Lucero Palau
2024-11-20 17:15 ` Dave Jiang
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-20 13:57 UTC (permalink / raw)
To: Dave Jiang, Zhi Wang
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On 11/19/24 21:27, Dave Jiang wrote:
>
> On 11/19/24 1:06 PM, Zhi Wang wrote:
>> On Tue, 19 Nov 2024 11:24:44 -0700
>> Dave Jiang <dave.jiang@intel.com> wrote:
>>
>>>
>>> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>>>> From: Alejandro Lucero <alucerop@amd.com>
>>>>
>>>> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device
>>>> when creating a memdev leading to problems when obtaining
>>>> cxl_memdev_state references from a CXL_DEVTYPE_DEVMEM type. This
>>>> last device type is managed by a specific vendor driver and does
>>>> not need same sysfs files since not userspace intervention is
>>>> expected.
>>>>
>>>> Create a new cxl_mem device type with no attributes for Type2.
>>>>
>>>> Avoid debugfs files relying on existence of clx_memdev_state.
>>>>
>>>> Make devm_cxl_add_memdev accesible from a accel driver.
>>>>
>>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>>> ---
>>>> drivers/cxl/core/cdat.c | 3 +++
>>>> drivers/cxl/core/memdev.c | 15 +++++++++++++--
>>>> drivers/cxl/core/region.c | 3 ++-
>>>> drivers/cxl/mem.c | 25 +++++++++++++++++++------
>>>> include/cxl/cxl.h | 2 ++
>>>> 5 files changed, 39 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
>>>> index e9cd7939c407..192cff18ea25 100644
>>>> --- a/drivers/cxl/core/cdat.c
>>>> +++ b/drivers/cxl/core/cdat.c
>>>> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf
>>>> *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle struct
>>>> cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct
>>>> cxl_dpa_perf *perf;
>>>> + if (!mds)
>>>> + return ERR_PTR(-EINVAL);
>>>> +
>>>> switch (mode) {
>>>> case CXL_DECODER_RAM:
>>>> perf = &mds->ram_perf;
>>>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>>>> index d746c8a1021c..df31eea0c06b 100644
>>>> --- a/drivers/cxl/core/memdev.c
>>>> +++ b/drivers/cxl/core/memdev.c
>>>> @@ -547,9 +547,17 @@ static const struct device_type
>>>> cxl_memdev_type = { .groups = cxl_memdev_attribute_groups,
>>>> };
>>>>
>>>> +static const struct device_type cxl_accel_memdev_type = {
>>>> + .name = "cxl_memdev",
>>>> + .release = cxl_memdev_release,
>>>> + .devnode = cxl_memdev_devnode,
>>>> +};
>>>> +
>>>> bool is_cxl_memdev(const struct device *dev)
>>>> {
>>>> - return dev->type == &cxl_memdev_type;
>>>> + return (dev->type == &cxl_memdev_type ||
>>>> + dev->type == &cxl_accel_memdev_type);
>>>> +
>>>> }
>>>> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
>>> Does type2 device also exports a CDAT?
>>>
>> Yes. Type2 can also export a CDAT.
> Thanks! Probably should have the split out helpers regardless.
Maybe, but should not we wait until that is required? I did not see the
need for adding them with this patchset.
>>> I'm also wondering if we should have distinctive helpers:
>>> is_cxl_type3_memdev()
>>> is_cxl_type2_memdev()
>>>
>>> and is_cxl_memdev() is just calling those two helpers above.
>>>
>>> And if no CDAT is exported, we should change the is_cxl_memdev() to
>>> is_cxl_type3_memdev() in read_cdat_data().
>>>
>>> DJ
>>>
>>>>
>>>> @@ -660,7 +668,10 @@ static struct cxl_memdev
>>>> *cxl_memdev_alloc(struct cxl_dev_state *cxlds, dev->parent =
>>>> cxlds->dev; dev->bus = &cxl_bus_type;
>>>> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
>>>> - dev->type = &cxl_memdev_type;
>>>> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
>>>> + dev->type = &cxl_accel_memdev_type;
>>>> + else
>>>> + dev->type = &cxl_memdev_type;
>>>> device_set_pm_not_required(dev);
>>>> INIT_WORK(&cxlmd->detach_work, detach_memdev);
>>>>
>>>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>>>> index dff618c708dc..622e3bb2e04b 100644
>>>> --- a/drivers/cxl/core/region.c
>>>> +++ b/drivers/cxl/core/region.c
>>>> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct
>>>> cxl_region *cxlr, return -EINVAL;
>>>> }
>>>>
>>>> - cxl_region_perf_data_calculate(cxlr, cxled);
>>>> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
>>>> + cxl_region_perf_data_calculate(cxlr, cxled);
>>>>
>>>> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
>>>> int i;
>>>> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
>>>> index a9fd5cd5a0d2..cb771bf196cd 100644
>>>> --- a/drivers/cxl/mem.c
>>>> +++ b/drivers/cxl/mem.c
>>>> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
>>>> dentry = cxl_debugfs_create_dir(dev_name(dev));
>>>> debugfs_create_devm_seqfile(dev, "dpamem", dentry,
>>>> cxl_mem_dpa_show);
>>>> - if (test_bit(CXL_POISON_ENABLED_INJECT,
>>>> mds->poison.enabled_cmds))
>>>> - debugfs_create_file("inject_poison", 0200, dentry,
>>>> cxlmd,
>>>> - &cxl_poison_inject_fops);
>>>> - if (test_bit(CXL_POISON_ENABLED_CLEAR,
>>>> mds->poison.enabled_cmds))
>>>> - debugfs_create_file("clear_poison", 0200, dentry,
>>>> cxlmd,
>>>> - &cxl_poison_clear_fops);
>>>> + /*
>>>> + * Avoid poison debugfs files for Type2 devices as they
>>>> rely on
>>>> + * cxl_memdev_state.
>>>> + */
>>>> + if (mds) {
>>>> + if (test_bit(CXL_POISON_ENABLED_INJECT,
>>>> mds->poison.enabled_cmds))
>>>> + debugfs_create_file("inject_poison", 0200,
>>>> dentry, cxlmd,
>>>> +
>>>> &cxl_poison_inject_fops);
>>>> + if (test_bit(CXL_POISON_ENABLED_CLEAR,
>>>> mds->poison.enabled_cmds))
>>>> + debugfs_create_file("clear_poison", 0200,
>>>> dentry, cxlmd,
>>>> +
>>>> &cxl_poison_clear_fops);
>>>> + }
>>>>
>>>> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
>>>> if (rc)
>>>> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject
>>>> *kobj, struct attribute *a, int n) struct cxl_memdev *cxlmd =
>>>> to_cxl_memdev(dev); struct cxl_memdev_state *mds =
>>>> to_cxl_memdev_state(cxlmd->cxlds);
>>>> + /*
>>>> + * Avoid poison sysfs files for Type2 devices as they rely
>>>> on
>>>> + * cxl_memdev_state.
>>>> + */
>>>> + if (!mds)
>>>> + return 0;
>>>> +
>>>> if (a == &dev_attr_trigger_poison_list.attr)
>>>> if (!test_bit(CXL_POISON_ENABLED_LIST,
>>>> mds->poison.enabled_cmds))
>>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>>> index 6033ce84b3d3..5608ed0f5f15 100644
>>>> --- a/include/cxl/cxl.h
>>>> +++ b/include/cxl/cxl.h
>>>> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev
>>>> *pdev, struct cxl_dev_state *cxlds); int
>>>> cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource
>>>> type); int cxl_release_resource(struct cxl_dev_state *cxlds, enum
>>>> cxl_resource type); void cxl_set_media_ready(struct cxl_dev_state
>>>> *cxlds); +struct cxl_memdev *devm_cxl_add_memdev(struct device
>>>> *host,
>>>> + struct cxl_dev_state
>>>> *cxlds); #endif
>>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-20 13:57 ` Alejandro Lucero Palau
@ 2024-11-20 17:15 ` Dave Jiang
2024-11-21 7:43 ` Zhi Wang
0 siblings, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-20 17:15 UTC (permalink / raw)
To: Alejandro Lucero Palau, Zhi Wang
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On 11/20/24 6:57 AM, Alejandro Lucero Palau wrote:
>
> On 11/19/24 21:27, Dave Jiang wrote:
>>
>> On 11/19/24 1:06 PM, Zhi Wang wrote:
>>> On Tue, 19 Nov 2024 11:24:44 -0700
>>> Dave Jiang <dave.jiang@intel.com> wrote:
>>>
>>>>
>>>> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>>>>> From: Alejandro Lucero <alucerop@amd.com>
>>>>>
>>>>> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device
>>>>> when creating a memdev leading to problems when obtaining
>>>>> cxl_memdev_state references from a CXL_DEVTYPE_DEVMEM type. This
>>>>> last device type is managed by a specific vendor driver and does
>>>>> not need same sysfs files since not userspace intervention is
>>>>> expected.
>>>>>
>>>>> Create a new cxl_mem device type with no attributes for Type2.
>>>>>
>>>>> Avoid debugfs files relying on existence of clx_memdev_state.
>>>>>
>>>>> Make devm_cxl_add_memdev accesible from a accel driver.
>>>>>
>>>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>>>> ---
>>>>> drivers/cxl/core/cdat.c | 3 +++
>>>>> drivers/cxl/core/memdev.c | 15 +++++++++++++--
>>>>> drivers/cxl/core/region.c | 3 ++-
>>>>> drivers/cxl/mem.c | 25 +++++++++++++++++++------
>>>>> include/cxl/cxl.h | 2 ++
>>>>> 5 files changed, 39 insertions(+), 9 deletions(-)
>>>>>
>>>>> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
>>>>> index e9cd7939c407..192cff18ea25 100644
>>>>> --- a/drivers/cxl/core/cdat.c
>>>>> +++ b/drivers/cxl/core/cdat.c
>>>>> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf
>>>>> *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle struct
>>>>> cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct
>>>>> cxl_dpa_perf *perf;
>>>>> + if (!mds)
>>>>> + return ERR_PTR(-EINVAL);
>>>>> +
>>>>> switch (mode) {
>>>>> case CXL_DECODER_RAM:
>>>>> perf = &mds->ram_perf;
>>>>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>>>>> index d746c8a1021c..df31eea0c06b 100644
>>>>> --- a/drivers/cxl/core/memdev.c
>>>>> +++ b/drivers/cxl/core/memdev.c
>>>>> @@ -547,9 +547,17 @@ static const struct device_type
>>>>> cxl_memdev_type = { .groups = cxl_memdev_attribute_groups,
>>>>> };
>>>>> +static const struct device_type cxl_accel_memdev_type = {
>>>>> + .name = "cxl_memdev",
>>>>> + .release = cxl_memdev_release,
>>>>> + .devnode = cxl_memdev_devnode,
>>>>> +};
>>>>> +
>>>>> bool is_cxl_memdev(const struct device *dev)
>>>>> {
>>>>> - return dev->type == &cxl_memdev_type;
>>>>> + return (dev->type == &cxl_memdev_type ||
>>>>> + dev->type == &cxl_accel_memdev_type);
>>>>> +
>>>>> }
>>>>> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
>>>> Does type2 device also exports a CDAT?
>>>>
>>> Yes. Type2 can also export a CDAT.
>> Thanks! Probably should have the split out helpers regardless.
>
>
> Maybe, but should not we wait until that is required? I did not see the need for adding them with this patchset.
Sure. I think my concern is with paths that apply only to one type but not the other. If you have not encountered any then we can wait.
DJ
>
>
>>>> I'm also wondering if we should have distinctive helpers:
>>>> is_cxl_type3_memdev()
>>>> is_cxl_type2_memdev()
>>>>
>>>> and is_cxl_memdev() is just calling those two helpers above.
>>>>
>>>> And if no CDAT is exported, we should change the is_cxl_memdev() to
>>>> is_cxl_type3_memdev() in read_cdat_data().
>>>>
>>>> DJ
>>>>
>>>>> @@ -660,7 +668,10 @@ static struct cxl_memdev
>>>>> *cxl_memdev_alloc(struct cxl_dev_state *cxlds, dev->parent =
>>>>> cxlds->dev; dev->bus = &cxl_bus_type;
>>>>> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
>>>>> - dev->type = &cxl_memdev_type;
>>>>> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
>>>>> + dev->type = &cxl_accel_memdev_type;
>>>>> + else
>>>>> + dev->type = &cxl_memdev_type;
>>>>> device_set_pm_not_required(dev);
>>>>> INIT_WORK(&cxlmd->detach_work, detach_memdev);
>>>>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>>>>> index dff618c708dc..622e3bb2e04b 100644
>>>>> --- a/drivers/cxl/core/region.c
>>>>> +++ b/drivers/cxl/core/region.c
>>>>> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct
>>>>> cxl_region *cxlr, return -EINVAL;
>>>>> }
>>>>> - cxl_region_perf_data_calculate(cxlr, cxled);
>>>>> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
>>>>> + cxl_region_perf_data_calculate(cxlr, cxled);
>>>>> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
>>>>> int i;
>>>>> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
>>>>> index a9fd5cd5a0d2..cb771bf196cd 100644
>>>>> --- a/drivers/cxl/mem.c
>>>>> +++ b/drivers/cxl/mem.c
>>>>> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
>>>>> dentry = cxl_debugfs_create_dir(dev_name(dev));
>>>>> debugfs_create_devm_seqfile(dev, "dpamem", dentry,
>>>>> cxl_mem_dpa_show);
>>>>> - if (test_bit(CXL_POISON_ENABLED_INJECT,
>>>>> mds->poison.enabled_cmds))
>>>>> - debugfs_create_file("inject_poison", 0200, dentry,
>>>>> cxlmd,
>>>>> - &cxl_poison_inject_fops);
>>>>> - if (test_bit(CXL_POISON_ENABLED_CLEAR,
>>>>> mds->poison.enabled_cmds))
>>>>> - debugfs_create_file("clear_poison", 0200, dentry,
>>>>> cxlmd,
>>>>> - &cxl_poison_clear_fops);
>>>>> + /*
>>>>> + * Avoid poison debugfs files for Type2 devices as they
>>>>> rely on
>>>>> + * cxl_memdev_state.
>>>>> + */
>>>>> + if (mds) {
>>>>> + if (test_bit(CXL_POISON_ENABLED_INJECT,
>>>>> mds->poison.enabled_cmds))
>>>>> + debugfs_create_file("inject_poison", 0200,
>>>>> dentry, cxlmd,
>>>>> +
>>>>> &cxl_poison_inject_fops);
>>>>> + if (test_bit(CXL_POISON_ENABLED_CLEAR,
>>>>> mds->poison.enabled_cmds))
>>>>> + debugfs_create_file("clear_poison", 0200,
>>>>> dentry, cxlmd,
>>>>> +
>>>>> &cxl_poison_clear_fops);
>>>>> + }
>>>>> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
>>>>> if (rc)
>>>>> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject
>>>>> *kobj, struct attribute *a, int n) struct cxl_memdev *cxlmd =
>>>>> to_cxl_memdev(dev); struct cxl_memdev_state *mds =
>>>>> to_cxl_memdev_state(cxlmd->cxlds);
>>>>> + /*
>>>>> + * Avoid poison sysfs files for Type2 devices as they rely
>>>>> on
>>>>> + * cxl_memdev_state.
>>>>> + */
>>>>> + if (!mds)
>>>>> + return 0;
>>>>> +
>>>>> if (a == &dev_attr_trigger_poison_list.attr)
>>>>> if (!test_bit(CXL_POISON_ENABLED_LIST,
>>>>> mds->poison.enabled_cmds))
>>>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>>>> index 6033ce84b3d3..5608ed0f5f15 100644
>>>>> --- a/include/cxl/cxl.h
>>>>> +++ b/include/cxl/cxl.h
>>>>> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev
>>>>> *pdev, struct cxl_dev_state *cxlds); int
>>>>> cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource
>>>>> type); int cxl_release_resource(struct cxl_dev_state *cxlds, enum
>>>>> cxl_resource type); void cxl_set_media_ready(struct cxl_dev_state
>>>>> *cxlds); +struct cxl_memdev *devm_cxl_add_memdev(struct device
>>>>> *host,
>>>>> + struct cxl_dev_state
>>>>> *cxlds); #endif
>>>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
2024-11-18 21:55 ` Dave Jiang
@ 2024-11-20 23:07 ` Fan Ni
2024-11-22 4:35 ` Alison Schofield
2024-11-22 20:43 ` Ben Cheatham
3 siblings, 0 replies; 99+ messages in thread
From: Fan Ni @ 2024-11-20 23:07 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, Nov 18, 2024 at 04:44:08PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Differentiate Type3, aka memory expanders, from Type2, aka device
> accelerators, with a new function for initializing cxl_dev_state.
>
> Create accessors to cxl_dev_state to be used by accel drivers.
>
> Based on previous work by Dan Williams [1]
>
> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Fan Ni <fan.ni@samsung.com>
> ---
> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
> drivers/cxl/core/pci.c | 1 +
> drivers/cxl/cxlpci.h | 16 ------------
> drivers/cxl/pci.c | 13 +++++++---
> include/cxl/cxl.h | 21 ++++++++++++++++
> include/cxl/pci.h | 23 ++++++++++++++++++
> 6 files changed, 105 insertions(+), 20 deletions(-)
> create mode 100644 include/cxl/cxl.h
> create mode 100644 include/cxl/pci.h
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index 84fefb76dafa..d083fd13a6dd 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. */
>
> +#include <cxl/cxl.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/firmware.h>
> #include <linux/device.h>
> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>
> static struct lock_class_key cxl_memdev_key;
>
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
> +{
> + struct cxl_dev_state *cxlds;
> +
> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
> + if (!cxlds)
> + return ERR_PTR(-ENOMEM);
> +
> + cxlds->dev = dev;
> + cxlds->type = CXL_DEVTYPE_DEVMEM;
> +
> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
> +
> + return cxlds;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
> +
> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> const struct file_operations *fops)
> {
> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
> return 0;
> }
>
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
> +{
> + cxlds->cxl_dvsec = dvsec;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
> +
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
> +{
> + cxlds->serial = serial;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
> +
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource type)
> +{
> + switch (type) {
> + case CXL_RES_DPA:
> + cxlds->dpa_res = res;
> + return 0;
> + case CXL_RES_RAM:
> + cxlds->ram_res = res;
> + return 0;
> + case CXL_RES_PMEM:
> + cxlds->pmem_res = res;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 420e4be85a1f..ff266e91ea71 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1,5 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
> +#include <cxl/pci.h>
> #include <linux/units.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/device.h>
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index 4da07727ab9c..eb59019fe5f3 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -14,22 +14,6 @@
> */
> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>
> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> -#define CXL_DVSEC_PCIE_DEVICE 0
> -#define CXL_DVSEC_CAP_OFFSET 0xA
> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> -#define CXL_DVSEC_CTRL_OFFSET 0xC
> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> -
> #define CXL_DVSEC_RANGE_MAX 2
>
> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 188412d45e0d..0b910ef52db7 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1,5 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
> #include <linux/unaligned.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/moduleparam.h>
> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> struct cxl_memdev *cxlmd;
> int i, rc, pmu_count;
> bool irq_avail;
> + u16 dvsec;
>
> /*
> * Double check the anonymous union trickery in struct cxl_regs
> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> pci_set_drvdata(pdev, cxlds);
>
> cxlds->rcd = is_cxl_restricted(pdev);
> - cxlds->serial = pci_get_dsn(pdev);
> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
> - if (!cxlds->cxl_dvsec)
> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
> + CXL_DVSEC_PCIE_DEVICE);
> + if (!dvsec)
> dev_warn(&pdev->dev,
> "Device DVSEC not present, skip CXL.mem init\n");
>
> + cxl_set_dvsec(cxlds, dvsec);
> +
> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> if (rc)
> return rc;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> new file mode 100644
> index 000000000000..19e5d883557a
> --- /dev/null
> +++ b/include/cxl/cxl.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
> +
> +#ifndef __CXL_H
> +#define __CXL_H
> +
> +#include <linux/ioport.h>
> +
> +enum cxl_resource {
> + CXL_RES_DPA,
> + CXL_RES_RAM,
> + CXL_RES_PMEM,
> +};
> +
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
> +
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource);
> +#endif
> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
> new file mode 100644
> index 000000000000..ad63560caa2c
> --- /dev/null
> +++ b/include/cxl/pci.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +
> +#ifndef __CXL_ACCEL_PCI_H
> +#define __CXL_ACCEL_PCI_H
> +
> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> +#define CXL_DVSEC_PCIE_DEVICE 0
> +#define CXL_DVSEC_CAP_OFFSET 0xA
> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> +#define CXL_DVSEC_CTRL_OFFSET 0xC
> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> +
> +#endif
> --
> 2.17.1
>
--
Fan Ni (From gmail)
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-18 16:44 ` [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources alejandro.lucero-palau
2024-11-19 18:00 ` Dave Jiang
2024-11-19 19:50 ` Zhi Wang
@ 2024-11-21 2:46 ` Alison Schofield
2024-11-21 9:22 ` Alejandro Lucero Palau
2 siblings, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-21 2:46 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, Nov 18, 2024 at 04:44:17PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> For a resource defined with size zero, resource_contains returns
> always true.
>
I'm not following the premise above -
Looking at resource_contains() and the changes made below,
it seems the concern is with &cxlds->ram_res or &cxlds->pmem_res
being zero - because we already checked that the second param
'res' is not zero a few lines above.
Looking at what happens when r1 is of size 0, I don't see how
resource_contains() returns always true.
In resource_contains(r1, r2), if r1 is of size 0, r1->start == r1->end.
The func can only return true if r2 is also of size 0 and located at
exactly r1->start. But, in this case, we are not going to get there
because we never send an r2 of size 0.
For any non-zero size r2 the func will always return false because
the size 0 r1 cannot encompass any range.
I could be misreading it all ;)
--Alison
> Add resource size check before using it.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/hdm.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index 223c273c0cd1..c58d6b8f9b58 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> cxled->dpa_res = res;
> cxled->skip = skipped;
>
> - if (resource_contains(&cxlds->pmem_res, res))
> + if (resource_size(&cxlds->pmem_res) &&
> + resource_contains(&cxlds->pmem_res, res)) {
> cxled->mode = CXL_DECODER_PMEM;
> - else if (resource_contains(&cxlds->ram_res, res))
> + } else if (resource_size(&cxlds->ram_res) &&
> + resource_contains(&cxlds->ram_res, res)) {
> cxled->mode = CXL_DECODER_RAM;
> + }
> else {
> dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
> port->id, cxled->cxld.id, cxled->dpa_res);
> --
> 2.17.1
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 26/27] cxl: add function for obtaining params from a region
2024-11-18 16:44 ` [PATCH v5 26/27] cxl: add function for obtaining params from a region alejandro.lucero-palau
2024-11-19 20:40 ` Zhi Wang
@ 2024-11-21 2:56 ` Alison Schofield
2024-11-27 17:18 ` Alejandro Lucero Palau
2024-11-21 16:31 ` Dave Jiang
2 siblings, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-21 2:56 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, Nov 18, 2024 at 04:44:33PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> A CXL region struct contains the physical address to work with.
>
> Add a function for given a opaque cxl region struct returns the params
> to be used for mapping such memory range.
I may not be understanding what needs to be opaque here.
Why not just 'add function to get a region resource'
and then add 'cxl_get_region_resource().
Region params usually refers to the member of struct cxl_region
that is called 'params' and that includes more than the resource.
--Alison
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/region.c | 16 ++++++++++++++++
> drivers/cxl/cxl.h | 2 ++
> include/cxl/cxl.h | 2 ++
> 3 files changed, 20 insertions(+)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index eff3ad788077..fa44a60549f7 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2663,6 +2663,22 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
> return ERR_PTR(rc);
> }
>
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end)
> +{
> + if (!region)
> + return -ENODEV;
> +
> + if (!region->params.res)
> + return -ENOSPC;
> +
> + *start = region->params.res->start;
> + *end = region->params.res->end;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_region_params, CXL);
> +
> static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
> {
> return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index ee3385db5663..7b46d313e581 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -913,6 +913,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
>
> bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
>
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end);
> /*
> * Unit test builds overrides this to __weak, find the 'strong' version
> * of these symbols in tools/testing/cxl/.
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 2a8ebabfc1dd..f14a3f292ad8 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -77,4 +77,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> bool avoid_dax);
>
> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end);
> #endif
> --
> 2.17.1
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 00/27] cxl: add type2 device basic support
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
` (26 preceding siblings ...)
2024-11-18 16:44 ` [PATCH v5 27/27] sfc: support pio mapping based on cxl alejandro.lucero-palau
@ 2024-11-21 3:33 ` Alison Schofield
2024-11-21 9:27 ` Alejandro Lucero Palau
27 siblings, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-21 3:33 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On Mon, Nov 18, 2024 at 04:44:07PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alejandro.lucero-palau@amd.com>
>
> v5 changes:
Hi Alejandro -
What is the base commit for this set? (I'm trying to apply it)
In future revs please include the base commit. I typically get it
by setting the upstream branch and then doing --base="auto" when
formatting the patches.
Thanks!
Alison
..snip
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-20 13:45 ` Alejandro Lucero Palau
@ 2024-11-21 7:13 ` Zhi Wang
0 siblings, 0 replies; 99+ messages in thread
From: Zhi Wang @ 2024-11-21 7:13 UTC (permalink / raw)
To: Alejandro Lucero Palau
Cc: Zhi Wang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On Wed, 20 Nov 2024 13:45:54 +0000
Alejandro Lucero Palau <alucerop@amd.com> wrote:
>
> On 11/19/24 19:50, Zhi Wang wrote:
> > On Mon, 18 Nov 2024 16:44:17 +0000
> > <alejandro.lucero-palau@amd.com> wrote:
> >
> >> From: Alejandro Lucero <alucerop@amd.com>
> >>
> >> For a resource defined with size zero, resource_contains returns
> >> always true.
> >>
> >> Add resource size check before using it.
> >>
> > Does this trigger a bug? Looks like this should be with a Fixes:
> > tag?
>
>
> It seems it does not until the new code for type2 support.
>
I see. Then it is not necessary for a Fixes: tag.
>
> > Z.
> >
> >> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> >> ---
> >> drivers/cxl/core/hdm.c | 7 +++++--
> >> 1 file changed, 5 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> >> index 223c273c0cd1..c58d6b8f9b58 100644
> >> --- a/drivers/cxl/core/hdm.c
> >> +++ b/drivers/cxl/core/hdm.c
> >> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct
> >> cxl_endpoint_decoder *cxled, cxled->dpa_res = res;
> >> cxled->skip = skipped;
> >>
> >> - if (resource_contains(&cxlds->pmem_res, res))
> >> + if (resource_size(&cxlds->pmem_res) &&
> >> + resource_contains(&cxlds->pmem_res, res)) {
> >> cxled->mode = CXL_DECODER_PMEM;
> >> - else if (resource_contains(&cxlds->ram_res, res))
> >> + } else if (resource_size(&cxlds->ram_res) &&
> >> + resource_contains(&cxlds->ram_res, res)) {
> >> cxled->mode = CXL_DECODER_RAM;
> >> + }
> >> else {
> >> dev_warn(dev, "decoder%d.%d: %pr mixed mode not
> >> supported\n", port->id, cxled->cxld.id, cxled->dpa_res);
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-20 17:15 ` Dave Jiang
@ 2024-11-21 7:43 ` Zhi Wang
0 siblings, 0 replies; 99+ messages in thread
From: Zhi Wang @ 2024-11-21 7:43 UTC (permalink / raw)
To: Dave Jiang
Cc: Alejandro Lucero Palau, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On Wed, 20 Nov 2024 10:15:59 -0700
Dave Jiang <dave.jiang@intel.com> wrote:
>
>
> On 11/20/24 6:57 AM, Alejandro Lucero Palau wrote:
> >
> > On 11/19/24 21:27, Dave Jiang wrote:
> >>
> >> On 11/19/24 1:06 PM, Zhi Wang wrote:
> >>> On Tue, 19 Nov 2024 11:24:44 -0700
> >>> Dave Jiang <dave.jiang@intel.com> wrote:
> >>>
> >>>>
> >>>> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> >>>>> From: Alejandro Lucero <alucerop@amd.com>
> >>>>>
> >>>>> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device
> >>>>> when creating a memdev leading to problems when obtaining
> >>>>> cxl_memdev_state references from a CXL_DEVTYPE_DEVMEM type. This
> >>>>> last device type is managed by a specific vendor driver and does
> >>>>> not need same sysfs files since not userspace intervention is
> >>>>> expected.
> >>>>>
> >>>>> Create a new cxl_mem device type with no attributes for Type2.
> >>>>>
> >>>>> Avoid debugfs files relying on existence of clx_memdev_state.
> >>>>>
> >>>>> Make devm_cxl_add_memdev accesible from a accel driver.
> >>>>>
> >>>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> >>>>> ---
> >>>>> drivers/cxl/core/cdat.c | 3 +++
> >>>>> drivers/cxl/core/memdev.c | 15 +++++++++++++--
> >>>>> drivers/cxl/core/region.c | 3 ++-
> >>>>> drivers/cxl/mem.c | 25 +++++++++++++++++++------
> >>>>> include/cxl/cxl.h | 2 ++
> >>>>> 5 files changed, 39 insertions(+), 9 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> >>>>> index e9cd7939c407..192cff18ea25 100644
> >>>>> --- a/drivers/cxl/core/cdat.c
> >>>>> +++ b/drivers/cxl/core/cdat.c
> >>>>> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf
> >>>>> *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle struct
> >>>>> cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct
> >>>>> cxl_dpa_perf *perf;
> >>>>> + if (!mds)
> >>>>> + return ERR_PTR(-EINVAL);
> >>>>> +
> >>>>> switch (mode) {
> >>>>> case CXL_DECODER_RAM:
> >>>>> perf = &mds->ram_perf;
> >>>>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> >>>>> index d746c8a1021c..df31eea0c06b 100644
> >>>>> --- a/drivers/cxl/core/memdev.c
> >>>>> +++ b/drivers/cxl/core/memdev.c
> >>>>> @@ -547,9 +547,17 @@ static const struct device_type
> >>>>> cxl_memdev_type = { .groups = cxl_memdev_attribute_groups,
> >>>>> };
> >>>>> +static const struct device_type cxl_accel_memdev_type = {
> >>>>> + .name = "cxl_memdev",
> >>>>> + .release = cxl_memdev_release,
> >>>>> + .devnode = cxl_memdev_devnode,
> >>>>> +};
> >>>>> +
> >>>>> bool is_cxl_memdev(const struct device *dev)
> >>>>> {
> >>>>> - return dev->type == &cxl_memdev_type;
> >>>>> + return (dev->type == &cxl_memdev_type ||
> >>>>> + dev->type == &cxl_accel_memdev_type);
> >>>>> +
> >>>>> }
> >>>>> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
> >>>> Does type2 device also exports a CDAT?
> >>>>
> >>> Yes. Type2 can also export a CDAT.
> >> Thanks! Probably should have the split out helpers regardless.
> >
> >
> > Maybe, but should not we wait until that is required? I did not see the need for adding them with this patchset.
>
> Sure. I think my concern is with paths that apply only to one type but not the other. If you have not encountered any then we can wait.
>
Agree.
I was thinking that for long-term, maybe CDAT routines shouldn't be tied to
device type, for me, it is like a cap that can be probed-and-used. E.g.
when talking with DOE, the core knows if CDAT is available or not, similar
case when the core tries to reach it via mailbox.
Z.
> DJ
>
> >
> >
> >>>> I'm also wondering if we should have distinctive helpers:
> >>>> is_cxl_type3_memdev()
> >>>> is_cxl_type2_memdev()
> >>>>
> >>>> and is_cxl_memdev() is just calling those two helpers above.
> >>>>
> >>>> And if no CDAT is exported, we should change the is_cxl_memdev() to
> >>>> is_cxl_type3_memdev() in read_cdat_data().
> >>>>
> >>>> DJ
> >>>>
> >>>>> @@ -660,7 +668,10 @@ static struct cxl_memdev
> >>>>> *cxl_memdev_alloc(struct cxl_dev_state *cxlds, dev->parent =
> >>>>> cxlds->dev; dev->bus = &cxl_bus_type;
> >>>>> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
> >>>>> - dev->type = &cxl_memdev_type;
> >>>>> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
> >>>>> + dev->type = &cxl_accel_memdev_type;
> >>>>> + else
> >>>>> + dev->type = &cxl_memdev_type;
> >>>>> device_set_pm_not_required(dev);
> >>>>> INIT_WORK(&cxlmd->detach_work, detach_memdev);
> >>>>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> >>>>> index dff618c708dc..622e3bb2e04b 100644
> >>>>> --- a/drivers/cxl/core/region.c
> >>>>> +++ b/drivers/cxl/core/region.c
> >>>>> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct
> >>>>> cxl_region *cxlr, return -EINVAL;
> >>>>> }
> >>>>> - cxl_region_perf_data_calculate(cxlr, cxled);
> >>>>> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
> >>>>> + cxl_region_perf_data_calculate(cxlr, cxled);
> >>>>> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
> >>>>> int i;
> >>>>> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
> >>>>> index a9fd5cd5a0d2..cb771bf196cd 100644
> >>>>> --- a/drivers/cxl/mem.c
> >>>>> +++ b/drivers/cxl/mem.c
> >>>>> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
> >>>>> dentry = cxl_debugfs_create_dir(dev_name(dev));
> >>>>> debugfs_create_devm_seqfile(dev, "dpamem", dentry,
> >>>>> cxl_mem_dpa_show);
> >>>>> - if (test_bit(CXL_POISON_ENABLED_INJECT,
> >>>>> mds->poison.enabled_cmds))
> >>>>> - debugfs_create_file("inject_poison", 0200, dentry,
> >>>>> cxlmd,
> >>>>> - &cxl_poison_inject_fops);
> >>>>> - if (test_bit(CXL_POISON_ENABLED_CLEAR,
> >>>>> mds->poison.enabled_cmds))
> >>>>> - debugfs_create_file("clear_poison", 0200, dentry,
> >>>>> cxlmd,
> >>>>> - &cxl_poison_clear_fops);
> >>>>> + /*
> >>>>> + * Avoid poison debugfs files for Type2 devices as they
> >>>>> rely on
> >>>>> + * cxl_memdev_state.
> >>>>> + */
> >>>>> + if (mds) {
> >>>>> + if (test_bit(CXL_POISON_ENABLED_INJECT,
> >>>>> mds->poison.enabled_cmds))
> >>>>> + debugfs_create_file("inject_poison", 0200,
> >>>>> dentry, cxlmd,
> >>>>> +
> >>>>> &cxl_poison_inject_fops);
> >>>>> + if (test_bit(CXL_POISON_ENABLED_CLEAR,
> >>>>> mds->poison.enabled_cmds))
> >>>>> + debugfs_create_file("clear_poison", 0200,
> >>>>> dentry, cxlmd,
> >>>>> +
> >>>>> &cxl_poison_clear_fops);
> >>>>> + }
> >>>>> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
> >>>>> if (rc)
> >>>>> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject
> >>>>> *kobj, struct attribute *a, int n) struct cxl_memdev *cxlmd =
> >>>>> to_cxl_memdev(dev); struct cxl_memdev_state *mds =
> >>>>> to_cxl_memdev_state(cxlmd->cxlds);
> >>>>> + /*
> >>>>> + * Avoid poison sysfs files for Type2 devices as they rely
> >>>>> on
> >>>>> + * cxl_memdev_state.
> >>>>> + */
> >>>>> + if (!mds)
> >>>>> + return 0;
> >>>>> +
> >>>>> if (a == &dev_attr_trigger_poison_list.attr)
> >>>>> if (!test_bit(CXL_POISON_ENABLED_LIST,
> >>>>> mds->poison.enabled_cmds))
> >>>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> >>>>> index 6033ce84b3d3..5608ed0f5f15 100644
> >>>>> --- a/include/cxl/cxl.h
> >>>>> +++ b/include/cxl/cxl.h
> >>>>> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev
> >>>>> *pdev, struct cxl_dev_state *cxlds); int
> >>>>> cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource
> >>>>> type); int cxl_release_resource(struct cxl_dev_state *cxlds, enum
> >>>>> cxl_resource type); void cxl_set_media_ready(struct cxl_dev_state
> >>>>> *cxlds); +struct cxl_memdev *devm_cxl_add_memdev(struct device
> >>>>> *host,
> >>>>> + struct cxl_dev_state
> >>>>> *cxlds); #endif
> >>>>
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-21 2:46 ` Alison Schofield
@ 2024-11-21 9:22 ` Alejandro Lucero Palau
2024-11-21 21:00 ` Alison Schofield
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-21 9:22 UTC (permalink / raw)
To: Alison Schofield, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/21/24 02:46, Alison Schofield wrote:
> On Mon, Nov 18, 2024 at 04:44:17PM +0000, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> For a resource defined with size zero, resource_contains returns
>> always true.
>>
> I'm not following the premise above -
>
> Looking at resource_contains() and the changes made below,
> it seems the concern is with &cxlds->ram_res or &cxlds->pmem_res
> being zero - because we already checked that the second param
> 'res' is not zero a few lines above.
>
> Looking at what happens when r1 is of size 0, I don't see how
> resource_contains() returns always true.
>
> In resource_contains(r1, r2), if r1 is of size 0, r1->start == r1->end.
> The func can only return true if r2 is also of size 0 and located at
> exactly r1->start. But, in this case, we are not going to get there
> because we never send an r2 of size 0.
>
> For any non-zero size r2 the func will always return false because
> the size 0 r1 cannot encompass any range.
>
> I could be misreading it all ;)
The key is to know how a resource with size 0 is initialized, what can
be understood looking at DEFINE_RES_NAMED macro. The end field is set
as size - 1.
With unsigned variables, as it is the case here, it means to have a
resource as big as possible ... if you do not check first the size is
not 0.
The pmem resource is explicitly initialized inside
cxl_accel_state_create in the previous patch, so it has:
pmem_res->start = 0, pmem_res.end = 0xffffffffffffffff
the resource checked against is defined with, for example, a 256MB size:
res.start =0, res.end = 0xfffffff
if you then use resource_contains(pmem_res, res), that implies always
true, whatever the res range defined.
All this confused me as well when facing it initially. I hope this
explanation makes sense.
>
> --Alison
>
>
>> Add resource size check before using it.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/hdm.c | 7 +++++--
>> 1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>> index 223c273c0cd1..c58d6b8f9b58 100644
>> --- a/drivers/cxl/core/hdm.c
>> +++ b/drivers/cxl/core/hdm.c
>> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
>> cxled->dpa_res = res;
>> cxled->skip = skipped;
>>
>> - if (resource_contains(&cxlds->pmem_res, res))
>> + if (resource_size(&cxlds->pmem_res) &&
>> + resource_contains(&cxlds->pmem_res, res)) {
>> cxled->mode = CXL_DECODER_PMEM;
>> - else if (resource_contains(&cxlds->ram_res, res))
>> + } else if (resource_size(&cxlds->ram_res) &&
>> + resource_contains(&cxlds->ram_res, res)) {
>> cxled->mode = CXL_DECODER_RAM;
>> + }
>> else {
>> dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
>> port->id, cxled->cxld.id, cxled->dpa_res);
>> --
>> 2.17.1
>>
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 00/27] cxl: add type2 device basic support
2024-11-21 3:33 ` [PATCH v5 00/27] cxl: add type2 device basic support Alison Schofield
@ 2024-11-21 9:27 ` Alejandro Lucero Palau
2024-11-22 4:14 ` Alison Schofield
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-21 9:27 UTC (permalink / raw)
To: Alison Schofield, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/21/24 03:33, Alison Schofield wrote:
> On Mon, Nov 18, 2024 at 04:44:07PM +0000, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alejandro.lucero-palau@amd.com>
>>
>> v5 changes:
> Hi Alejandro -
Hi Allison,
> What is the base commit for this set? (I'm trying to apply it)
I'm not using the CXL tree but Linus one, and using 6.12-rc7
> In future revs please include the base commit. I typically get it
> by setting the upstream branch and then doing --base="auto" when
> formatting the patches.
Apologies for the inconveniences. I'll do so for v6, which will use 6.13
Thanks
>
> Thanks!
> Alison
>
> ..snip
>
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 19/27] cxl: make region type based on endpoint type
2024-11-18 16:44 ` [PATCH v5 19/27] cxl: make region type based on endpoint type alejandro.lucero-palau
2024-11-19 20:16 ` Zhi Wang
@ 2024-11-21 16:16 ` Dave Jiang
1 sibling, 0 replies; 99+ messages in thread
From: Dave Jiang @ 2024-11-21 16:16 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Current code is expecting Type3 or CXL_DECODER_HOSTONLYMEM devices only.
> Support for Type2 implies region type needs to be based on the endpoint
> type instead.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/region.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index d107cc1b4350..8e2dbd15cfc0 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2654,7 +2654,8 @@ static ssize_t create_ram_region_show(struct device *dev,
> }
>
> static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
> - enum cxl_decoder_mode mode, int id)
> + enum cxl_decoder_mode mode, int id,
> + enum cxl_decoder_type target_type)
> {
> int rc;
>
> @@ -2676,7 +2677,7 @@ static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
> return ERR_PTR(-EBUSY);
> }
>
> - return devm_cxl_add_region(cxlrd, id, mode, CXL_DECODER_HOSTONLYMEM);
> + return devm_cxl_add_region(cxlrd, id, mode, target_type);
> }
>
> static ssize_t create_pmem_region_store(struct device *dev,
> @@ -2691,7 +2692,8 @@ static ssize_t create_pmem_region_store(struct device *dev,
> if (rc != 1)
> return -EINVAL;
>
> - cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id);
> + cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id,
> + CXL_DECODER_HOSTONLYMEM);
> if (IS_ERR(cxlr))
> return PTR_ERR(cxlr);
>
> @@ -2711,7 +2713,8 @@ static ssize_t create_ram_region_store(struct device *dev,
> if (rc != 1)
> return -EINVAL;
>
> - cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id);
> + cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id,
> + CXL_DECODER_HOSTONLYMEM);
> if (IS_ERR(cxlr))
> return PTR_ERR(cxlr);
>
> @@ -3372,7 +3375,8 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>
> do {
> cxlr = __create_region(cxlrd, cxled->mode,
> - atomic_read(&cxlrd->region_id));
> + atomic_read(&cxlrd->region_id),
> + cxled->cxld.target_type);
> } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
>
> if (IS_ERR(cxlr)) {
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 20/27] cxl/region: factor out interleave ways setup
2024-11-18 16:44 ` [PATCH v5 20/27] cxl/region: factor out interleave ways setup alejandro.lucero-palau
2024-11-19 20:20 ` Zhi Wang
@ 2024-11-21 16:23 ` Dave Jiang
1 sibling, 0 replies; 99+ messages in thread
From: Dave Jiang @ 2024-11-21 16:23 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> In preparation for kernel driven region creation, factor out a common
> helper from the user-sysfs region setup for interleave ways.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/region.c | 46 +++++++++++++++++++++++----------------
> 1 file changed, 27 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 8e2dbd15cfc0..04f82adb763f 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -464,22 +464,14 @@ static ssize_t interleave_ways_show(struct device *dev,
>
> static const struct attribute_group *get_cxl_region_target_group(void);
>
> -static ssize_t interleave_ways_store(struct device *dev,
> - struct device_attribute *attr,
> - const char *buf, size_t len)
> +static int set_interleave_ways(struct cxl_region *cxlr, int val)
> {
> - struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent);
> + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
> struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
> - struct cxl_region *cxlr = to_cxl_region(dev);
> struct cxl_region_params *p = &cxlr->params;
> - unsigned int val, save;
> - int rc;
> + int save, rc;
> u8 iw;
>
> - rc = kstrtouint(buf, 0, &val);
> - if (rc)
> - return rc;
> -
> rc = ways_to_eiw(val, &iw);
> if (rc)
> return rc;
> @@ -494,20 +486,36 @@ static ssize_t interleave_ways_store(struct device *dev,
> return -EINVAL;
> }
>
> - rc = down_write_killable(&cxl_region_rwsem);
> - if (rc)
> - return rc;
> - if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
> - rc = -EBUSY;
> - goto out;
> - }
> + lockdep_assert_held_write(&cxl_region_rwsem);
> + if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
> + return -EBUSY;
>
> save = p->interleave_ways;
> p->interleave_ways = val;
> rc = sysfs_update_group(&cxlr->dev.kobj, get_cxl_region_target_group());
> if (rc)
> p->interleave_ways = save;
> -out:
> +
> + return rc;
> +}
> +
> +static ssize_t interleave_ways_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct cxl_region *cxlr = to_cxl_region(dev);
> + unsigned int val;
> + int rc;
> +
> + rc = kstrtouint(buf, 0, &val);
> + if (rc)
> + return rc;
> +
> + rc = down_write_killable(&cxl_region_rwsem);
> + if (rc)
> + return rc;
> +
> + rc = set_interleave_ways(cxlr, val);
> up_write(&cxl_region_rwsem);
> if (rc)
> return rc;
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 21/27] cxl/region: factor out interleave granularity setup
2024-11-18 16:44 ` [PATCH v5 21/27] cxl/region: factor out interleave granularity setup alejandro.lucero-palau
2024-11-19 20:23 ` Zhi Wang
@ 2024-11-21 16:24 ` Dave Jiang
1 sibling, 0 replies; 99+ messages in thread
From: Dave Jiang @ 2024-11-21 16:24 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> In preparation for kernel driven region creation, factor out a common
> helper from the user-sysfs region setup for interleave granularity.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
> drivers/cxl/core/region.c | 39 +++++++++++++++++++++++----------------
> 1 file changed, 23 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 04f82adb763f..6652887ea396 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -540,21 +540,14 @@ static ssize_t interleave_granularity_show(struct device *dev,
> return rc;
> }
>
> -static ssize_t interleave_granularity_store(struct device *dev,
> - struct device_attribute *attr,
> - const char *buf, size_t len)
> +static int set_interleave_granularity(struct cxl_region *cxlr, int val)
> {
> - struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent);
> + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
> struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
> - struct cxl_region *cxlr = to_cxl_region(dev);
> struct cxl_region_params *p = &cxlr->params;
> - int rc, val;
> + int rc;
> u16 ig;
>
> - rc = kstrtoint(buf, 0, &val);
> - if (rc)
> - return rc;
> -
> rc = granularity_to_eig(val, &ig);
> if (rc)
> return rc;
> @@ -570,16 +563,30 @@ static ssize_t interleave_granularity_store(struct device *dev,
> if (cxld->interleave_ways > 1 && val != cxld->interleave_granularity)
> return -EINVAL;
>
> + lockdep_assert_held_write(&cxl_region_rwsem);
> + if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
> + return -EBUSY;
> +
> + p->interleave_granularity = val;
> + return 0;
> +}
> +
> +static ssize_t interleave_granularity_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct cxl_region *cxlr = to_cxl_region(dev);
> + int rc, val;
> +
> + rc = kstrtoint(buf, 0, &val);
> + if (rc)
> + return rc;
> +
> rc = down_write_killable(&cxl_region_rwsem);
> if (rc)
> return rc;
> - if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
> - rc = -EBUSY;
> - goto out;
> - }
>
> - p->interleave_granularity = val;
> -out:
> + rc = set_interleave_granularity(cxlr, val);
> up_write(&cxl_region_rwsem);
> if (rc)
> return rc;
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 26/27] cxl: add function for obtaining params from a region
2024-11-18 16:44 ` [PATCH v5 26/27] cxl: add function for obtaining params from a region alejandro.lucero-palau
2024-11-19 20:40 ` Zhi Wang
2024-11-21 2:56 ` Alison Schofield
@ 2024-11-21 16:31 ` Dave Jiang
2024-11-27 17:12 ` Alejandro Lucero Palau
2 siblings, 1 reply; 99+ messages in thread
From: Dave Jiang @ 2024-11-21 16:31 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> A CXL region struct contains the physical address to work with.
>
> Add a function for given a opaque cxl region struct returns the params
> to be used for mapping such memory range.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/region.c | 16 ++++++++++++++++
> drivers/cxl/cxl.h | 2 ++
> include/cxl/cxl.h | 2 ++
> 3 files changed, 20 insertions(+)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index eff3ad788077..fa44a60549f7 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2663,6 +2663,22 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
> return ERR_PTR(rc);
> }
>
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end)
Maybe just pass in a 'struct range' ptr and call it cxl_get_region_range()?
DJ
> +{
> + if (!region)
> + return -ENODEV;
> +
> + if (!region->params.res)
> + return -ENOSPC;
> +
> + *start = region->params.res->start;
> + *end = region->params.res->end;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_region_params, CXL);
> +
> static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
> {
> return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index ee3385db5663..7b46d313e581 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -913,6 +913,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
>
> bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
>
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end);
> /*
> * Unit test builds overrides this to __weak, find the 'strong' version
> * of these symbols in tools/testing/cxl/.
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 2a8ebabfc1dd..f14a3f292ad8 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -77,4 +77,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> bool avoid_dax);
>
> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
> + resource_size_t *end);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-21 9:22 ` Alejandro Lucero Palau
@ 2024-11-21 21:00 ` Alison Schofield
2024-11-27 14:56 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-21 21:00 UTC (permalink / raw)
To: Alejandro Lucero Palau
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On Thu, Nov 21, 2024 at 09:22:33AM +0000, Alejandro Lucero Palau wrote:
>
> On 11/21/24 02:46, Alison Schofield wrote:
> > On Mon, Nov 18, 2024 at 04:44:17PM +0000, alejandro.lucero-palau@amd.com wrote:
> > > From: Alejandro Lucero <alucerop@amd.com>
> > >
> > > For a resource defined with size zero, resource_contains returns
> > > always true.
> > >
> > I'm not following the premise above -
> >
> > Looking at resource_contains() and the changes made below,
> > it seems the concern is with &cxlds->ram_res or &cxlds->pmem_res
> > being zero - because we already checked that the second param
> > 'res' is not zero a few lines above.
> >
> > Looking at what happens when r1 is of size 0, I don't see how
> > resource_contains() returns always true.
> >
> > In resource_contains(r1, r2), if r1 is of size 0, r1->start == r1->end.
> > The func can only return true if r2 is also of size 0 and located at
> > exactly r1->start. But, in this case, we are not going to get there
> > because we never send an r2 of size 0.
> >
> > For any non-zero size r2 the func will always return false because
> > the size 0 r1 cannot encompass any range.
> >
> > I could be misreading it all ;)
>
>
> The key is to know how a resource with size 0 is initialized, what can be
> understood looking at DEFINE_RES_NAMED macro. The end field is set as size
> - 1.
>
> With unsigned variables, as it is the case here, it means to have a resource
> as big as possible ... if you do not check first the size is not 0.
>
> The pmem resource is explicitly initialized inside cxl_accel_state_create in
> the previous patch, so it has:
>
> pmem_res->start = 0, pmem_res.end = 0xffffffffffffffff
>
> the resource checked against is defined with, for example, a 256MB size:
>
> res.start =0, res.end = 0xfffffff
>
>
> if you then use resource_contains(pmem_res, res), that implies always true,
> whatever the res range defined.
>
>
> All this confused me as well when facing it initially. I hope this
> explanation makes sense.
>
Thanks for the explanation! I'm wondering if we are leaving a trap for the next
developer.
resource_contains() seems to have intended that a check for IORESOURCE_UNSET
would take care of the zero size case:
(5edb93b89f6c resource: Add resource_contains)
and it would if folks used _UNSET. Some check r1->start before calling
resource_contains().
One option would be to use _UNSET in this case, but that only covers us here,
and doesn't remove the trap ;)
How about hardening resource_contains():
ie: make resource_contains() return false if either res empty
/* True iff r1 completely contains r2 */
static inline bool resource_contains(const struct resource *r1, const struct resource *r2)
{
+ if (!resource_size(r1) || !resource_size(r2))
+ return false;
if (resource_type(r1) != resource_type(r2))
return false;
if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET)
return false;
return r1->start <= r2->start && r1->end >= r2->end;
}
-- Alison
> >
> > --Alison
> >
> >
> > > Add resource size check before using it.
> > >
> > > Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> > > ---
> > > drivers/cxl/core/hdm.c | 7 +++++--
> > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> > > index 223c273c0cd1..c58d6b8f9b58 100644
> > > --- a/drivers/cxl/core/hdm.c
> > > +++ b/drivers/cxl/core/hdm.c
> > > @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> > > cxled->dpa_res = res;
> > > cxled->skip = skipped;
> > > - if (resource_contains(&cxlds->pmem_res, res))
> > > + if (resource_size(&cxlds->pmem_res) &&
> > > + resource_contains(&cxlds->pmem_res, res)) {
> > > cxled->mode = CXL_DECODER_PMEM;
> > > - else if (resource_contains(&cxlds->ram_res, res))
> > > + } else if (resource_size(&cxlds->ram_res) &&
> > > + resource_contains(&cxlds->ram_res, res)) {
> > > cxled->mode = CXL_DECODER_RAM;
> > > + }
> > > else {
> > > dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
> > > port->id, cxled->cxld.id, cxled->dpa_res);
> > > --
> > > 2.17.1
> > >
> > >
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 06/27] cxl: add function for type2 cxl regs setup
2024-11-18 16:44 ` [PATCH v5 06/27] cxl: add function for type2 cxl regs setup alejandro.lucero-palau
2024-11-18 23:32 ` Dave Jiang
@ 2024-11-21 22:34 ` Alison Schofield
2024-11-27 11:46 ` Alejandro Lucero Palau
1 sibling, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-21 22:34 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, Nov 18, 2024 at 04:44:13PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Create a new function for a type2 device initialising
> cxl_dev_state struct regarding cxl regs setup and mapping.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/pci.c | 47 ++++++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 2 ++
> 2 files changed, 49 insertions(+)
>
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
snip
> +
> +int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds)
> +{
> + int rc;
maybe init to 0
> +
> + rc = cxl_pci_setup_memdev_regs(pdev, cxlds);
> + if (rc)
> + return rc;
> +
> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
> + &cxlds->reg_map, cxlds->capabilities);
> + if (rc) {
> + dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
> + return rc;
> + }
> +
> + if (!test_bit(CXL_CM_CAP_CAP_ID_RAS, cxlds->capabilities))
> + return rc;
init rc to 0 or return 0 directly here
> +
> + rc = cxl_map_component_regs(&cxlds->reg_map,
> + &cxlds->regs.component,
> + BIT(CXL_CM_CAP_CAP_ID_RAS));
> + if (rc)
> + dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
> +
> + return rc;
init rc to 0 or return 0 directly here
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_pci_accel_setup_regs, CXL);
snip
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 00/27] cxl: add type2 device basic support
2024-11-21 9:27 ` Alejandro Lucero Palau
@ 2024-11-22 4:14 ` Alison Schofield
0 siblings, 0 replies; 99+ messages in thread
From: Alison Schofield @ 2024-11-22 4:14 UTC (permalink / raw)
To: Alejandro Lucero Palau
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On Thu, Nov 21, 2024 at 09:27:34AM +0000, Alejandro Lucero Palau wrote:
>
> On 11/21/24 03:33, Alison Schofield wrote:
> > On Mon, Nov 18, 2024 at 04:44:07PM +0000, alejandro.lucero-palau@amd.com wrote:
> > > From: Alejandro Lucero <alejandro.lucero-palau@amd.com>
> > >
> > > v5 changes:
> > Hi Alejandro -
>
>
> Hi Allison,
>
>
> > What is the base commit for this set? (I'm trying to apply it)
>
>
> I'm not using the CXL tree but Linus one, and using 6.12-rc7
>
That would've been my next guess ;)
I applied w the intent of trying cxl-test but was not able to
build image including the cxl-test module because of a circular dependency:
cxl_core -> cxl_mock -> cxl_core
That happens at Patch 1. I'll comment a bit there...
-- Alison
>
> > In future revs please include the base commit. I typically get it
> > by setting the upstream branch and then doing --base="auto" when
> > formatting the patches.
>
>
> Apologies for the inconveniences. I'll do so for v6, which will use 6.13
>
> Thanks
>
>
> >
> > Thanks!
> > Alison
> >
> > ..snip
> >
> > >
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
2024-11-18 21:55 ` Dave Jiang
2024-11-20 23:07 ` Fan Ni
@ 2024-11-22 4:35 ` Alison Schofield
2024-11-22 9:27 ` Alejandro Lucero Palau
2024-11-22 20:43 ` Ben Cheatham
3 siblings, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-22 4:35 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, Nov 18, 2024 at 04:44:08PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Differentiate Type3, aka memory expanders, from Type2, aka device
> accelerators, with a new function for initializing cxl_dev_state.
>
> Create accessors to cxl_dev_state to be used by accel drivers.
>
> Based on previous work by Dan Williams [1]
>
> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
> drivers/cxl/core/pci.c | 1 +
> drivers/cxl/cxlpci.h | 16 ------------
> drivers/cxl/pci.c | 13 +++++++---
> include/cxl/cxl.h | 21 ++++++++++++++++
As I mentioned in the cover letter, beginning w the first patch
I have depmod issues building with the cxl-test module. I didn't
get very far figuring it out, other than a work-around of moving
the contents of include/cxl/cxl.h down into drivers/cxl/cxlmem.h.
That band-aid got me a bit further. In fact I wasn't so concerned
with breaking sfx as I was with regression testing the changes to
drivers/cxl/.
Please see if you can get the cxl-test module working again.
> include/cxl/pci.h | 23 ++++++++++++++++++
> 6 files changed, 105 insertions(+), 20 deletions(-)
> create mode 100644 include/cxl/cxl.h
> create mode 100644 include/cxl/pci.h
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index 84fefb76dafa..d083fd13a6dd 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. */
>
> +#include <cxl/cxl.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/firmware.h>
> #include <linux/device.h>
> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>
> static struct lock_class_key cxl_memdev_key;
>
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
> +{
> + struct cxl_dev_state *cxlds;
> +
> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
> + if (!cxlds)
> + return ERR_PTR(-ENOMEM);
> +
> + cxlds->dev = dev;
> + cxlds->type = CXL_DEVTYPE_DEVMEM;
> +
> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
> +
> + return cxlds;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
> +
> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> const struct file_operations *fops)
> {
> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
> return 0;
> }
>
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
> +{
> + cxlds->cxl_dvsec = dvsec;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
> +
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
> +{
> + cxlds->serial = serial;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
> +
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource type)
> +{
> + switch (type) {
> + case CXL_RES_DPA:
> + cxlds->dpa_res = res;
> + return 0;
> + case CXL_RES_RAM:
> + cxlds->ram_res = res;
> + return 0;
> + case CXL_RES_PMEM:
> + cxlds->pmem_res = res;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 420e4be85a1f..ff266e91ea71 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1,5 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
> +#include <cxl/pci.h>
> #include <linux/units.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/device.h>
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index 4da07727ab9c..eb59019fe5f3 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -14,22 +14,6 @@
> */
> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>
> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> -#define CXL_DVSEC_PCIE_DEVICE 0
> -#define CXL_DVSEC_CAP_OFFSET 0xA
> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> -#define CXL_DVSEC_CTRL_OFFSET 0xC
> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> -
> #define CXL_DVSEC_RANGE_MAX 2
>
> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 188412d45e0d..0b910ef52db7 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1,5 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
> #include <linux/unaligned.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/moduleparam.h>
> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> struct cxl_memdev *cxlmd;
> int i, rc, pmu_count;
> bool irq_avail;
> + u16 dvsec;
>
> /*
> * Double check the anonymous union trickery in struct cxl_regs
> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> pci_set_drvdata(pdev, cxlds);
>
> cxlds->rcd = is_cxl_restricted(pdev);
> - cxlds->serial = pci_get_dsn(pdev);
> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
> - if (!cxlds->cxl_dvsec)
> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
> + CXL_DVSEC_PCIE_DEVICE);
> + if (!dvsec)
> dev_warn(&pdev->dev,
> "Device DVSEC not present, skip CXL.mem init\n");
>
> + cxl_set_dvsec(cxlds, dvsec);
> +
> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> if (rc)
> return rc;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> new file mode 100644
> index 000000000000..19e5d883557a
> --- /dev/null
> +++ b/include/cxl/cxl.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
> +
> +#ifndef __CXL_H
> +#define __CXL_H
> +
> +#include <linux/ioport.h>
> +
> +enum cxl_resource {
> + CXL_RES_DPA,
> + CXL_RES_RAM,
> + CXL_RES_PMEM,
> +};
> +
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
> +
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource);
> +#endif
> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
> new file mode 100644
> index 000000000000..ad63560caa2c
> --- /dev/null
> +++ b/include/cxl/pci.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +
> +#ifndef __CXL_ACCEL_PCI_H
> +#define __CXL_ACCEL_PCI_H
> +
> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> +#define CXL_DVSEC_PCIE_DEVICE 0
> +#define CXL_DVSEC_CAP_OFFSET 0xA
> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> +#define CXL_DVSEC_CTRL_OFFSET 0xC
> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> +
> +#endif
> --
> 2.17.1
>
>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-22 4:35 ` Alison Schofield
@ 2024-11-22 9:27 ` Alejandro Lucero Palau
2024-11-26 5:59 ` Alison Schofield
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-22 9:27 UTC (permalink / raw)
To: Alison Schofield, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/22/24 04:35, Alison Schofield wrote:
> On Mon, Nov 18, 2024 at 04:44:08PM +0000, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Differentiate Type3, aka memory expanders, from Type2, aka device
>> accelerators, with a new function for initializing cxl_dev_state.
>>
>> Create accessors to cxl_dev_state to be used by accel drivers.
>>
>> Based on previous work by Dan Williams [1]
>>
>> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
>> ---
>> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
>> drivers/cxl/core/pci.c | 1 +
>> drivers/cxl/cxlpci.h | 16 ------------
>> drivers/cxl/pci.c | 13 +++++++---
>> include/cxl/cxl.h | 21 ++++++++++++++++
> As I mentioned in the cover letter, beginning w the first patch
> I have depmod issues building with the cxl-test module. I didn't
> get very far figuring it out, other than a work-around of moving
> the contents of include/cxl/cxl.h down into drivers/cxl/cxlmem.h.
> That band-aid got me a bit further. In fact I wasn't so concerned
> with breaking sfx as I was with regression testing the changes to
> drivers/cxl/.
>
> Please see if you can get the cxl-test module working again.
Hi Allison,
I have no problems building tools/testing/cxl and I can see cxl_test.ko
in tools/testing/cxl/test
I did try with the full patchset applied over 6.12-rc7 tag, and also
with only the first patch since I was not sure if you meant the build
after each patch is tried, but both worked once I modified the config
for the checks inside config_check.c not to fail.
I guess you meant this cxl test and not the one related to "git clone
https://github.com/moking/cxl-test-tool.git" what I have no experience with.
Could someone else try this as well?
>
>> include/cxl/pci.h | 23 ++++++++++++++++++
>> 6 files changed, 105 insertions(+), 20 deletions(-)
>> create mode 100644 include/cxl/cxl.h
>> create mode 100644 include/cxl/pci.h
>>
>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>> index 84fefb76dafa..d083fd13a6dd 100644
>> --- a/drivers/cxl/core/memdev.c
>> +++ b/drivers/cxl/core/memdev.c
>> @@ -1,6 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2020 Intel Corporation. */
>>
>> +#include <cxl/cxl.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/firmware.h>
>> #include <linux/device.h>
>> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>>
>> static struct lock_class_key cxl_memdev_key;
>>
>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
>> +{
>> + struct cxl_dev_state *cxlds;
>> +
>> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
>> + if (!cxlds)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + cxlds->dev = dev;
>> + cxlds->type = CXL_DEVTYPE_DEVMEM;
>> +
>> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
>> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
>> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
>> +
>> + return cxlds;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
>> +
>> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
>> const struct file_operations *fops)
>> {
>> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
>> return 0;
>> }
>>
>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
>> +{
>> + cxlds->cxl_dvsec = dvsec;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
>> +
>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
>> +{
>> + cxlds->serial = serial;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
>> +
>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> + enum cxl_resource type)
>> +{
>> + switch (type) {
>> + case CXL_RES_DPA:
>> + cxlds->dpa_res = res;
>> + return 0;
>> + case CXL_RES_RAM:
>> + cxlds->ram_res = res;
>> + return 0;
>> + case CXL_RES_PMEM:
>> + cxlds->pmem_res = res;
>> + return 0;
>> + }
>> +
>> + return -EINVAL;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
>> +
>> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
>> {
>> struct cxl_memdev *cxlmd =
>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
>> index 420e4be85a1f..ff266e91ea71 100644
>> --- a/drivers/cxl/core/pci.c
>> +++ b/drivers/cxl/core/pci.c
>> @@ -1,5 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
>> +#include <cxl/pci.h>
>> #include <linux/units.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/device.h>
>> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
>> index 4da07727ab9c..eb59019fe5f3 100644
>> --- a/drivers/cxl/cxlpci.h
>> +++ b/drivers/cxl/cxlpci.h
>> @@ -14,22 +14,6 @@
>> */
>> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>>
>> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>> -#define CXL_DVSEC_PCIE_DEVICE 0
>> -#define CXL_DVSEC_CAP_OFFSET 0xA
>> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>> -#define CXL_DVSEC_CTRL_OFFSET 0xC
>> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
>> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
>> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
>> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
>> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
>> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>> -
>> #define CXL_DVSEC_RANGE_MAX 2
>>
>> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>> index 188412d45e0d..0b910ef52db7 100644
>> --- a/drivers/cxl/pci.c
>> +++ b/drivers/cxl/pci.c
>> @@ -1,5 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>> +#include <cxl/cxl.h>
>> +#include <cxl/pci.h>
>> #include <linux/unaligned.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/moduleparam.h>
>> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> struct cxl_memdev *cxlmd;
>> int i, rc, pmu_count;
>> bool irq_avail;
>> + u16 dvsec;
>>
>> /*
>> * Double check the anonymous union trickery in struct cxl_regs
>> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> pci_set_drvdata(pdev, cxlds);
>>
>> cxlds->rcd = is_cxl_restricted(pdev);
>> - cxlds->serial = pci_get_dsn(pdev);
>> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
>> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
>> - if (!cxlds->cxl_dvsec)
>> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
>> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
>> + CXL_DVSEC_PCIE_DEVICE);
>> + if (!dvsec)
>> dev_warn(&pdev->dev,
>> "Device DVSEC not present, skip CXL.mem init\n");
>>
>> + cxl_set_dvsec(cxlds, dvsec);
>> +
>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>> if (rc)
>> return rc;
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> new file mode 100644
>> index 000000000000..19e5d883557a
>> --- /dev/null
>> +++ b/include/cxl/cxl.h
>> @@ -0,0 +1,21 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
>> +
>> +#ifndef __CXL_H
>> +#define __CXL_H
>> +
>> +#include <linux/ioport.h>
>> +
>> +enum cxl_resource {
>> + CXL_RES_DPA,
>> + CXL_RES_RAM,
>> + CXL_RES_PMEM,
>> +};
>> +
>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>> +
>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> + enum cxl_resource);
>> +#endif
>> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
>> new file mode 100644
>> index 000000000000..ad63560caa2c
>> --- /dev/null
>> +++ b/include/cxl/pci.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>> +
>> +#ifndef __CXL_ACCEL_PCI_H
>> +#define __CXL_ACCEL_PCI_H
>> +
>> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>> +#define CXL_DVSEC_PCIE_DEVICE 0
>> +#define CXL_DVSEC_CAP_OFFSET 0xA
>> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>> +#define CXL_DVSEC_CTRL_OFFSET 0xC
>> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
>> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
>> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
>> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
>> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
>> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>> +
>> +#endif
>> --
>> 2.17.1
>>
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 02/27] sfc: add cxl support using new CXL API
2024-11-18 16:44 ` [PATCH v5 02/27] sfc: add cxl support using new CXL API alejandro.lucero-palau
@ 2024-11-22 20:43 ` Ben Cheatham
2024-11-27 9:15 ` Alejandro Lucero Palau
2024-11-26 18:08 ` Fan Ni
1 sibling, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:43 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Add CXL initialization based on new CXL API for accel drivers and make
> it dependable on kernel CXL configuration.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/net/ethernet/sfc/Kconfig | 7 +++
> drivers/net/ethernet/sfc/Makefile | 1 +
> drivers/net/ethernet/sfc/efx.c | 24 +++++++-
> drivers/net/ethernet/sfc/efx_cxl.c | 88 +++++++++++++++++++++++++++
> drivers/net/ethernet/sfc/efx_cxl.h | 28 +++++++++
> drivers/net/ethernet/sfc/net_driver.h | 10 +++
> 6 files changed, 157 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
>
> diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
> index 3eb55dcfa8a6..a8bc777baa95 100644
> --- a/drivers/net/ethernet/sfc/Kconfig
> +++ b/drivers/net/ethernet/sfc/Kconfig
> @@ -65,6 +65,13 @@ config SFC_MCDI_LOGGING
> Driver-Interface) commands and responses, allowing debugging of
> driver/firmware interaction. The tracing is actually enabled by
> a sysfs file 'mcdi_logging' under the PCI device.
> +config SFC_CXL
> + bool "Solarflare SFC9100-family CXL support"
> + depends on SFC && CXL_BUS && !(SFC=y && CXL_BUS=m)
If I'm reading this right, you want to make sure that CXL_BUS is not set to 'm' when SFC is built-in. If that's
the case, you can simplify this to "depends on SFC && CXL_BUS && CXL_BUS >= SFC" (or SFC <= CXL_BUS).
I'm pretty sure you could also drop the middle part as well, so it would become "depends on SFC && CXL_BUS >= SFC".
Also, this patch relies on the cxl_mem/cxl_acpi modules, right? If so, I would change the CXL_BUS above to one of
those since they already depend on CXL_BUS IIRC.
> + default y
> + help
> + This enables CXL support by the driver relying on kernel support
> + and hardware support.
I think it would be good here to say what kernel support is being relied on. I'm 99% sure
it's just the CXL driver, so saying it relies on the CXL driver/module(s) would be fine. I
have no clue what hardware is needed for this support, so I can't make a recommendation
there.
>
> source "drivers/net/ethernet/sfc/falcon/Kconfig"
> source "drivers/net/ethernet/sfc/siena/Kconfig"
> diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
> index 8f446b9bd5ee..e909cafd5908 100644
> --- a/drivers/net/ethernet/sfc/Makefile
> +++ b/drivers/net/ethernet/sfc/Makefile
> @@ -13,6 +13,7 @@ sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
> mae.o tc.o tc_bindings.o tc_counters.o \
> tc_encap_actions.o tc_conntrack.o
>
> +sfc-$(CONFIG_SFC_CXL) += efx_cxl.o
> obj-$(CONFIG_SFC) += sfc.o
>
> obj-$(CONFIG_SFC_FALCON) += falcon/
> diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
> index 36b3b57e2055..5f7c910a14a5 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -33,6 +33,9 @@
> #include "selftest.h"
> #include "sriov.h"
> #include "efx_devlink.h"
> +#ifdef CONFIG_SFC_CXL
> +#include "efx_cxl.h"
> +#endif
>
> #include "mcdi_port_common.h"
> #include "mcdi_pcol.h"
> @@ -903,12 +906,17 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
> efx_pci_remove_main(efx);
>
> efx_fini_io(efx);
> +
> + probe_data = container_of(efx, struct efx_probe_data, efx);
> +#ifdef CONFIG_SFC_CXL
> + efx_cxl_exit(probe_data);
> +#endif
> +
> pci_dbg(efx->pci_dev, "shutdown successful\n");
>
> efx_fini_devlink_and_unlock(efx);
> efx_fini_struct(efx);
> free_netdev(efx->net_dev);
> - probe_data = container_of(efx, struct efx_probe_data, efx);
> kfree(probe_data);
> };
>
> @@ -1113,6 +1121,17 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
> if (rc)
> goto fail2;
>
> +#ifdef CONFIG_SFC_CXL
> + /* A successful cxl initialization implies a CXL region created to be
> + * used for PIO buffers. If there is no CXL support, or initialization
> + * fails, efx_cxl_pio_initialised wll be false and legacy PIO buffers
> + * defined at specific PCI BAR regions will be used.
> + */
> + rc = efx_cxl_init(probe_data);
> + if (rc)
> + pci_err(pci_dev, "CXL initialization failed with error %d\n", rc);
> +
> +#endif
> rc = efx_pci_probe_post_io(efx);
> if (rc) {
> /* On failure, retry once immediately.
> @@ -1384,3 +1403,6 @@ MODULE_AUTHOR("Solarflare Communications and "
> MODULE_DESCRIPTION("Solarflare network driver");
> MODULE_LICENSE("GPL");
> MODULE_DEVICE_TABLE(pci, efx_pci_table);
> +#ifdef CONFIG_SFC_CXL
> +MODULE_SOFTDEP("pre: cxl_core cxl_port cxl_acpi cxl-mem");
> +#endif
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> new file mode 100644
> index 000000000000..99f396028639
> --- /dev/null
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/****************************************************************************
> + *
> + * Driver for AMD network controllers and boards
> + * Copyright (C) 2024, Advanced Micro Devices, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation, incorporated herein by reference.
> + */
> +
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
> +#include <linux/pci.h>
> +
> +#include "net_driver.h"
> +#include "efx_cxl.h"
> +
> +#define EFX_CTPIO_BUFFER_SIZE SZ_256M
> +
> +int efx_cxl_init(struct efx_probe_data *probe_data)
> +{
> + struct efx_nic *efx = &probe_data->efx;
> + struct pci_dev *pci_dev;
> + struct efx_cxl *cxl;
> + struct resource res;
> + u16 dvsec;
> + int rc;
> +
> + pci_dev = efx->pci_dev;
> + probe_data->cxl_pio_initialised = false;
> +
> + dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
> + CXL_DVSEC_PCIE_DEVICE);
> + if (!dvsec)
> + return 0;
> +
> + pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
> +
> + cxl = kzalloc(sizeof(*cxl), GFP_KERNEL);
> + if (!cxl)
> + return -ENOMEM;
> +
> + cxl->cxlds = cxl_accel_state_create(&pci_dev->dev);
> + if (IS_ERR(cxl->cxlds)) {
> + pci_err(pci_dev, "CXL accel device state failed");
> + rc = -ENOMEM;
> + goto err1;
> + }
> +
> + cxl_set_dvsec(cxl->cxlds, dvsec);
> + cxl_set_serial(cxl->cxlds, pci_dev->dev.id);
> +
> + res = DEFINE_RES_MEM(0, EFX_CTPIO_BUFFER_SIZE);
> + if (cxl_set_resource(cxl->cxlds, res, CXL_RES_DPA)) {
> + pci_err(pci_dev, "cxl_set_resource DPA failed\n");
> + rc = -EINVAL;
> + goto err2;
> + }
> +
> + res = DEFINE_RES_MEM_NAMED(0, EFX_CTPIO_BUFFER_SIZE, "ram");
> + if (cxl_set_resource(cxl->cxlds, res, CXL_RES_RAM)) {
> + pci_err(pci_dev, "cxl_set_resource RAM failed\n");
> + rc = -EINVAL;
> + goto err2;
> + }
> +
> + probe_data->cxl = cxl;
> +
> + return 0;
> +
> +err2:
> + kfree(cxl->cxlds);
> +err1:
> + kfree(cxl);
> + return rc;
> +
> +}
> +
> +void efx_cxl_exit(struct efx_probe_data *probe_data)
> +{
> + if (probe_data->cxl) {
> + kfree(probe_data->cxl->cxlds);
> + kfree(probe_data->cxl);
> + }
> +}
> +
> +MODULE_IMPORT_NS(CXL);
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
> new file mode 100644
> index 000000000000..90fa46bc94db
> --- /dev/null
> +++ b/drivers/net/ethernet/sfc/efx_cxl.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/****************************************************************************
> + * Driver for AMD network controllers and boards
> + * Copyright (C) 2024, Advanced Micro Devices, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation, incorporated herein by reference.
> + */
> +
> +#ifndef EFX_CXL_H
> +#define EFX_CXL_H
> +
> +struct efx_nic;
> +
> +struct efx_cxl {
> + struct cxl_dev_state *cxlds;
> + struct cxl_memdev *cxlmd;
> + struct cxl_root_decoder *cxlrd;
> + struct cxl_port *endpoint;
> + struct cxl_endpoint_decoder *cxled;
> + struct cxl_region *efx_region;
> + void __iomem *ctpio_cxl;
> +};
> +
> +int efx_cxl_init(struct efx_probe_data *probe_data);
> +void efx_cxl_exit(struct efx_probe_data *probe_data);
> +#endif
I know nothing about the /net code so sorry if this is just a style thing, but
you can delete the #ifdef CONFIG_SFC_CXL in efx.c (and elsewhere) if you add stubs
for when CONFIG_SFC_CXL=n. So the above would look like:
#if IS_ENABLED(CONFIG_SFC_CXL) // or #ifdef CONFIG_SFC_CXL
int efx_cxl_init(struct efx_probe_data *probe_data);
void efx_cxl_exit(struct efx_probe_data *probe_data);
#else
static inline int efx_cxl_init(struct efx_probe_data *probe_data) { return 0; }
static inline void efx_cxl_exit(struct efx_probe_data *probe_data) {}
#endif
and then you can just #include efx_cxl.h unconditionally.
> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
> index b85c51cbe7f9..efc6d90380b9 100644
> --- a/drivers/net/ethernet/sfc/net_driver.h
> +++ b/drivers/net/ethernet/sfc/net_driver.h
> @@ -1160,14 +1160,24 @@ struct efx_nic {
> atomic_t n_rx_noskb_drops;
> };
>
> +#ifdef CONFIG_SFC_CXL
> +struct efx_cxl;
> +#endif
> +
> /**
> * struct efx_probe_data - State after hardware probe
> * @pci_dev: The PCI device
> * @efx: Efx NIC details
> + * @cxl: details of related cxl objects
> + * @cxl_pio_initialised: cxl initialization outcome.
> */
> struct efx_probe_data {
> struct pci_dev *pci_dev;
> struct efx_nic efx;
> +#ifdef CONFIG_SFC_CXL
> + struct efx_cxl *cxl;
> + bool cxl_pio_initialised;
> +#endif
> };
>
> static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
` (2 preceding siblings ...)
2024-11-22 4:35 ` Alison Schofield
@ 2024-11-22 20:43 ` Ben Cheatham
2024-11-27 9:00 ` Alejandro Lucero Palau
3 siblings, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:43 UTC (permalink / raw)
To: Lucero Palau, Alejandro
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Differentiate Type3, aka memory expanders, from Type2, aka device
> accelerators, with a new function for initializing cxl_dev_state.
>
> Create accessors to cxl_dev_state to be used by accel drivers.
>
> Based on previous work by Dan Williams [1]
>
> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
> drivers/cxl/core/pci.c | 1 +
> drivers/cxl/cxlpci.h | 16 ------------
> drivers/cxl/pci.c | 13 +++++++---
> include/cxl/cxl.h | 21 ++++++++++++++++
> include/cxl/pci.h | 23 ++++++++++++++++++
> 6 files changed, 105 insertions(+), 20 deletions(-)
> create mode 100644 include/cxl/cxl.h
> create mode 100644 include/cxl/pci.h
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index 84fefb76dafa..d083fd13a6dd 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. */
>
> +#include <cxl/cxl.h>
Pedantic one, you'll want this at the end CXL does reverse christmas tree
for #includes.
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/firmware.h>
> #include <linux/device.h>
> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>
> static struct lock_class_key cxl_memdev_key;
>
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
> +{
> + struct cxl_dev_state *cxlds;
> +
> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
Would it be better to use a devm_kzalloc() here? I'd imagine this function
will be called as part of probe a majority of the time so I think the automatic
cleanup would be nice here. If you did that, then I'd also rename the function to
include devm_ as well.
> + if (!cxlds)
> + return ERR_PTR(-ENOMEM);
> +
> + cxlds->dev = dev;
> + cxlds->type = CXL_DEVTYPE_DEVMEM;
> +
> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
> +
> + return cxlds;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
> +
> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> const struct file_operations *fops)
> {
> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
> return 0;
> }
>
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
> +{
> + cxlds->cxl_dvsec = dvsec;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
> +
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
> +{
> + cxlds->serial = serial;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
> +
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource type)
> +{
> + switch (type) {
> + case CXL_RES_DPA:
> + cxlds->dpa_res = res;
> + return 0;
> + case CXL_RES_RAM:
> + cxlds->ram_res = res;
> + return 0;
> + case CXL_RES_PMEM:
> + cxlds->pmem_res = res;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 420e4be85a1f..ff266e91ea71 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1,5 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
> +#include <cxl/pci.h>
> #include <linux/units.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/device.h>
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index 4da07727ab9c..eb59019fe5f3 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -14,22 +14,6 @@
> */
> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>
> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> -#define CXL_DVSEC_PCIE_DEVICE 0
> -#define CXL_DVSEC_CAP_OFFSET 0xA
> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> -#define CXL_DVSEC_CTRL_OFFSET 0xC
> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> -
> #define CXL_DVSEC_RANGE_MAX 2
>
> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 188412d45e0d..0b910ef52db7 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1,5 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
> #include <linux/unaligned.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <linux/moduleparam.h>
> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> struct cxl_memdev *cxlmd;
> int i, rc, pmu_count;
> bool irq_avail;
> + u16 dvsec;
>
> /*
> * Double check the anonymous union trickery in struct cxl_regs
> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> pci_set_drvdata(pdev, cxlds);
>
> cxlds->rcd = is_cxl_restricted(pdev);
> - cxlds->serial = pci_get_dsn(pdev);
> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
> - if (!cxlds->cxl_dvsec)
> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
> + CXL_DVSEC_PCIE_DEVICE);
> + if (!dvsec)
> dev_warn(&pdev->dev,
> "Device DVSEC not present, skip CXL.mem init\n");
>
> + cxl_set_dvsec(cxlds, dvsec);
> +
> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> if (rc)
> return rc;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> new file mode 100644
> index 000000000000..19e5d883557a
> --- /dev/null
> +++ b/include/cxl/cxl.h
Is cxl.h the right name for this file? I initially thought this was the cxl.h
under drivers/cxl. It looks like it's just type 2 related functions, so maybe
"type2.h", or "accel.h" would be better? If the plan is to expose more CXL
functionality not necessarily related to type 2 devices later I'm fine with it,
and if no one else cares then I'm fine with it.
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
> +
> +#ifndef __CXL_H
> +#define __CXL_H
> +
> +#include <linux/ioport.h>
> +
> +enum cxl_resource {
> + CXL_RES_DPA,
> + CXL_RES_RAM,
> + CXL_RES_PMEM,
> +};
> +
> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
> +
> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> + enum cxl_resource);
> +#endif
> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
> new file mode 100644
> index 000000000000..ad63560caa2c
> --- /dev/null
> +++ b/include/cxl/pci.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> +
> +#ifndef __CXL_ACCEL_PCI_H
> +#define __CXL_ACCEL_PCI_H
> +
> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> +#define CXL_DVSEC_PCIE_DEVICE 0
> +#define CXL_DVSEC_CAP_OFFSET 0xA
> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> +#define CXL_DVSEC_CTRL_OFFSET 0xC
> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> +
> +#endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port
2024-11-18 16:44 ` [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port alejandro.lucero-palau
2024-11-18 22:52 ` Dave Jiang
@ 2024-11-22 20:44 ` Ben Cheatham
1 sibling, 0 replies; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:44 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Type2 devices have some Type3 functionalities as optional like an mbox
> or an hdm decoder, and CXL core needs a way to know what an CXL accelerator
> implements.
>
> Add a new field to cxl_dev_state for keeping device capabilities as discovered
> during initialization. Add same field to cxl_port as registers discovery
> is also used during port initialization.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Dave already mentioned the one error I saw. With that fixed LGTM, so:
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> ---
> drivers/cxl/core/port.c | 11 +++++++----
> drivers/cxl/core/regs.c | 21 ++++++++++++++-------
> drivers/cxl/cxl.h | 9 ++++++---
> drivers/cxl/cxlmem.h | 2 ++
> drivers/cxl/pci.c | 10 ++++++----
> include/cxl/cxl.h | 30 ++++++++++++++++++++++++++++++
> 6 files changed, 65 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index af92c67bc954..5bc8490a199c 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -749,7 +749,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
> }
>
> static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map,
> - resource_size_t component_reg_phys)
> + resource_size_t component_reg_phys, unsigned long *caps)
> {
> *map = (struct cxl_register_map) {
> .host = host,
> @@ -763,7 +763,7 @@ static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map
> map->reg_type = CXL_REGLOC_RBI_COMPONENT;
> map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
>
> - return cxl_setup_regs(map);
> + return cxl_setup_regs(map, caps);
> }
>
> static int cxl_port_setup_regs(struct cxl_port *port,
> @@ -772,7 +772,7 @@ static int cxl_port_setup_regs(struct cxl_port *port,
> if (dev_is_platform(port->uport_dev))
> return 0;
> return cxl_setup_comp_regs(&port->dev, &port->reg_map,
> - component_reg_phys);
> + component_reg_phys, port->capabilities);
> }
>
> static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
> @@ -789,7 +789,8 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,
> * NULL.
> */
> rc = cxl_setup_comp_regs(dport->dport_dev, &dport->reg_map,
> - component_reg_phys);
> + component_reg_phys,
> + dport->port->capabilities);
> dport->reg_map.host = host;
> return rc;
> }
> @@ -851,6 +852,8 @@ static int cxl_port_add(struct cxl_port *port,
> port->reg_map = cxlds->reg_map;
> port->reg_map.host = &port->dev;
> cxlmd->endpoint = port;
> + bitmap_copy(port->capabilities, cxlds->capabilities,
> + CXL_MAX_CAPS);
> } else if (parent_dport) {
> rc = dev_set_name(dev, "port%d", port->id);
> if (rc)
> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
> index e1082e749c69..8287ec45b018 100644
> --- a/drivers/cxl/core/regs.c
> +++ b/drivers/cxl/core/regs.c
> @@ -4,6 +4,7 @@
> #include <linux/device.h>
> #include <linux/slab.h>
> #include <linux/pci.h>
> +#include <cxl/cxl.h>
> #include <cxlmem.h>
> #include <cxlpci.h>
> #include <pmu.h>
> @@ -36,7 +37,8 @@
> * Probe for component register information and return it in map object.
> */
> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> - struct cxl_component_reg_map *map)
> + struct cxl_component_reg_map *map,
> + unsigned long *caps)
> {
> int cap, cap_count;
> u32 cap_array;
> @@ -84,6 +86,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> decoder_cnt = cxl_hdm_decoder_count(hdr);
> length = 0x20 * decoder_cnt + 0x10;
> rmap = &map->hdm_decoder;
> + *caps |= BIT(CXL_DEV_CAP_HDM);
> break;
> }
> case CXL_CM_CAP_CAP_ID_RAS:
> @@ -91,6 +94,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> offset);
> length = CXL_RAS_CAPABILITY_LENGTH;
> rmap = &map->ras;
> + *caps |= BIT(CXL_DEV_CAP_RAS);
> break;
> default:
> dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
> @@ -117,7 +121,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);
> * Probe for device register information and return it in map object.
> */
> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> - struct cxl_device_reg_map *map)
> + struct cxl_device_reg_map *map, unsigned long *caps)
> {
> int cap, cap_count;
> u64 cap_array;
> @@ -146,10 +150,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
> dev_dbg(dev, "found Status capability (0x%x)\n", offset);
> rmap = &map->status;
> + *caps |= BIT(CXL_DEV_CAP_DEV_STATUS);
> break;
> case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
> dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
> rmap = &map->mbox;
> + *caps |= BIT(CXL_DEV_CAP_MAILBOX_PRIMARY);
> break;
> case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
> dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
> @@ -157,6 +163,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> case CXLDEV_CAP_CAP_ID_MEMDEV:
> dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
> rmap = &map->memdev;
> + *caps |= BIT(CXL_DEV_CAP_MEMDEV);
> break;
> default:
> if (cap_id >= 0x8000)
> @@ -421,7 +428,7 @@ static void cxl_unmap_regblock(struct cxl_register_map *map)
> map->base = NULL;
> }
>
> -static int cxl_probe_regs(struct cxl_register_map *map)
> +static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
> {
> struct cxl_component_reg_map *comp_map;
> struct cxl_device_reg_map *dev_map;
> @@ -431,12 +438,12 @@ static int cxl_probe_regs(struct cxl_register_map *map)
> switch (map->reg_type) {
> case CXL_REGLOC_RBI_COMPONENT:
> comp_map = &map->component_map;
> - cxl_probe_component_regs(host, base, comp_map);
> + cxl_probe_component_regs(host, base, comp_map, caps);
> dev_dbg(host, "Set up component registers\n");
> break;
> case CXL_REGLOC_RBI_MEMDEV:
> dev_map = &map->device_map;
> - cxl_probe_device_regs(host, base, dev_map);
> + cxl_probe_device_regs(host, base, dev_map, caps);
> if (!dev_map->status.valid || !dev_map->mbox.valid ||
> !dev_map->memdev.valid) {
> dev_err(host, "registers not found: %s%s%s\n",
> @@ -455,7 +462,7 @@ static int cxl_probe_regs(struct cxl_register_map *map)
> return 0;
> }
>
> -int cxl_setup_regs(struct cxl_register_map *map)
> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps)
> {
> int rc;
>
> @@ -463,7 +470,7 @@ int cxl_setup_regs(struct cxl_register_map *map)
> if (rc)
> return rc;
>
> - rc = cxl_probe_regs(map);
> + rc = cxl_probe_regs(map, caps);
> cxl_unmap_regblock(map);
>
> return rc;
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index a2be05fd7aa2..e5f918be6fe4 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -4,6 +4,7 @@
> #ifndef __CXL_H__
> #define __CXL_H__
>
> +#include <cxl/cxl.h>
> #include <linux/libnvdimm.h>
> #include <linux/bitfield.h>
> #include <linux/notifier.h>
> @@ -284,9 +285,9 @@ struct cxl_register_map {
> };
>
> void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> - struct cxl_component_reg_map *map);
> + struct cxl_component_reg_map *map, unsigned long *caps);
> void cxl_probe_device_regs(struct device *dev, void __iomem *base,
> - struct cxl_device_reg_map *map);
> + struct cxl_device_reg_map *map, unsigned long *caps);
> int cxl_map_component_regs(const struct cxl_register_map *map,
> struct cxl_component_regs *regs,
> unsigned long map_mask);
> @@ -300,7 +301,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
> struct cxl_register_map *map, int index);
> int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
> struct cxl_register_map *map);
> -int cxl_setup_regs(struct cxl_register_map *map);
> +int cxl_setup_regs(struct cxl_register_map *map, unsigned long *caps);
> struct cxl_dport;
> resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
> struct cxl_dport *dport);
> @@ -600,6 +601,7 @@ struct cxl_dax_region {
> * @cdat: Cached CDAT data
> * @cdat_available: Should a CDAT attribute be available in sysfs
> * @pci_latency: Upstream latency in picoseconds
> + * @capabilities: those capabilities as defined in device mapped registers
> */
> struct cxl_port {
> struct device dev;
> @@ -623,6 +625,7 @@ struct cxl_port {
> } cdat;
> bool cdat_available;
> long pci_latency;
> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
> };
>
> /**
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 2a25d1957ddb..4c1c53c29544 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -428,6 +428,7 @@ struct cxl_dpa_perf {
> * @serial: PCIe Device Serial Number
> * @type: Generic Memory Class device or Vendor Specific Memory device
> * @cxl_mbox: CXL mailbox context
> + * @capabilities: those capabilities as defined in device mapped registers
> */
> struct cxl_dev_state {
> struct device *dev;
> @@ -443,6 +444,7 @@ struct cxl_dev_state {
> u64 serial;
> enum cxl_devtype type;
> struct cxl_mailbox cxl_mbox;
> + DECLARE_BITMAP(capabilities, CXL_MAX_CAPS);
> };
>
> static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 0b910ef52db7..528d4ca79fd1 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -504,7 +504,8 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
> }
>
> static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> - struct cxl_register_map *map)
> + struct cxl_register_map *map,
> + unsigned long *caps)
> {
> int rc;
>
> @@ -521,7 +522,7 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> if (rc)
> return rc;
>
> - return cxl_setup_regs(map);
> + return cxl_setup_regs(map, caps);
> }
>
> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
> @@ -848,7 +849,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>
> cxl_set_dvsec(cxlds, dvsec);
>
> - rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map,
> + cxlds->capabilities);
> if (rc)
> return rc;
>
> @@ -861,7 +863,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> * still be useful for management functions so don't return an error.
> */
> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
> - &cxlds->reg_map);
> + &cxlds->reg_map, cxlds->capabilities);
> if (rc)
> dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
> else if (!cxlds->reg_map.component_map.ras.valid)
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 19e5d883557a..dcc9ec8a0aec 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -12,6 +12,36 @@ enum cxl_resource {
> CXL_RES_PMEM,
> };
>
> +/* Capabilities as defined for:
> + *
> + * Component Registers (Table 8-22 CXL 3.1 specification)
> + * Device Registers (8.2.8.2.1 CXL 3.1 specification)
> + */
> +
> +enum cxl_dev_cap {
> + /* capabilities from Component Registers */
> + CXL_DEV_CAP_RAS,
> + CXL_DEV_CAP_SEC,
> + CXL_DEV_CAP_LINK,
> + CXL_DEV_CAP_HDM,
> + CXL_DEV_CAP_SEC_EXT,
> + CXL_DEV_CAP_IDE,
> + CXL_DEV_CAP_SNOOP_FILTER,
> + CXL_DEV_CAP_TIMEOUT_AND_ISOLATION,
> + CXL_DEV_CAP_CACHEMEM_EXT,
> + CXL_DEV_CAP_BI_ROUTE_TABLE,
> + CXL_DEV_CAP_BI_DECODER,
> + CXL_DEV_CAP_CACHEID_ROUTE_TABLE,
> + CXL_DEV_CAP_CACHEID_DECODER,
> + CXL_DEV_CAP_HDM_EXT,
> + CXL_DEV_CAP_METADATA_EXT,
> + /* capabilities from Device Registers */
> + CXL_DEV_CAP_DEV_STATUS,
> + CXL_DEV_CAP_MAILBOX_PRIMARY,
> + CXL_DEV_CAP_MEMDEV,
> + CXL_MAX_CAPS = 32
> +};
> +
> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>
> void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 04/27] cxl/pci: add check for validating capabilities
2024-11-18 16:44 ` [PATCH v5 04/27] cxl/pci: add check for validating capabilities alejandro.lucero-palau
@ 2024-11-22 20:44 ` Ben Cheatham
2024-11-27 11:34 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:44 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> During CXL device initialization supported capabilities by the device
> are discovered. Type3 and Type2 devices have different mandatory
> capabilities and a Type2 expects a specific set including optional
> capabilities.
>
> Add a function for checking expected capabilities against those found
> during initialization. Allow those mandatory/expected capabilities to
> be a subset of the capabilities found.
>
> Rely on this function for validating capabilities instead of when CXL
> regs are probed.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/pci.c | 22 ++++++++++++++++++++++
> drivers/cxl/core/regs.c | 9 ---------
> drivers/cxl/pci.c | 24 ++++++++++++++++++++++++
> include/cxl/cxl.h | 6 +++++-
> 4 files changed, 51 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index ff266e91ea71..a1942b7be0bc 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -8,6 +8,7 @@
> #include <linux/pci.h>
> #include <linux/pci-doe.h>
> #include <linux/aer.h>
> +#include <cxl/cxl.h>
> #include <cxlpci.h>
> #include <cxlmem.h>
> #include <cxl.h>
> @@ -1055,3 +1056,24 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
>
> return 0;
> }
> +
> +bool cxl_pci_check_caps(struct cxl_dev_state *cxlds, unsigned long *expected_caps,
> + unsigned long *current_caps, bool is_subset)
> +{
> + DECLARE_BITMAP(subset, CXL_MAX_CAPS);
> +
> + if (current_caps)
> + bitmap_copy(current_caps, cxlds->capabilities, CXL_MAX_CAPS);
> +
> + dev_dbg(cxlds->dev, "Checking cxlds caps 0x%08lx vs expected caps 0x%08lx\n",
> + *cxlds->capabilities, *expected_caps);
> +
> + /* Checking a minimum of mandatory capabilities? */
> + if (is_subset) {
> + bitmap_and(subset, cxlds->capabilities, expected_caps, CXL_MAX_CAPS);
> + return bitmap_equal(subset, expected_caps, CXL_MAX_CAPS);
It looks like there's a function called bitmap_subset(), does that not do the above? I didn't
look at the function since it's the end of the day when I'm writing this and my brain is tired,
but I'd rather that be used if possible. I also don't think you need this is_subset parameter and
else branch. I don't see anyone using this function where some expected capabilities are optional
and others mandatory. If that's the case then they'd probably split the calls instead.
> + } else {
> + return bitmap_equal(cxlds->capabilities, expected_caps, CXL_MAX_CAPS);
> + }
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_pci_check_caps, CXL);
> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
> index 8287ec45b018..3b3965706414 100644
> --- a/drivers/cxl/core/regs.c
> +++ b/drivers/cxl/core/regs.c
> @@ -444,15 +444,6 @@ static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
> case CXL_REGLOC_RBI_MEMDEV:
> dev_map = &map->device_map;
> cxl_probe_device_regs(host, base, dev_map, caps);
> - if (!dev_map->status.valid || !dev_map->mbox.valid ||
> - !dev_map->memdev.valid) {
> - dev_err(host, "registers not found: %s%s%s\n",
> - !dev_map->status.valid ? "status " : "",
> - !dev_map->mbox.valid ? "mbox " : "",
> - !dev_map->memdev.valid ? "memdev " : "");
> - return -ENXIO;
> - }
> -
> dev_dbg(host, "Probing device registers...\n");
> break;
> default:
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 528d4ca79fd1..5de1473a79da 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -813,6 +813,8 @@ static int cxl_pci_type3_init_mailbox(struct cxl_dev_state *cxlds)
> static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> {
> struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
> + DECLARE_BITMAP(expected, CXL_MAX_CAPS);
> + DECLARE_BITMAP(found, CXL_MAX_CAPS);
> struct cxl_memdev_state *mds;
> struct cxl_dev_state *cxlds;
> struct cxl_register_map map;
> @@ -874,6 +876,28 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> if (rc)
> dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
>
> + bitmap_clear(expected, 0, CXL_MAX_CAPS);
> +
> + /*
> + * These are the mandatory capabilities for a Type3 device.
> + * Only checking capabilities used by current Linux drivers.
> + */
> + bitmap_set(expected, CXL_DEV_CAP_HDM, 1);
> + bitmap_set(expected, CXL_DEV_CAP_DEV_STATUS, 1);
> + bitmap_set(expected, CXL_DEV_CAP_MAILBOX_PRIMARY, 1);
> + bitmap_set(expected, CXL_DEV_CAP_DEV_STATUS, 1);
> +
> + /*
> + * Checking mandatory caps are there as, at least, a subset of those
> + * found.
> + */
> + if (!cxl_pci_check_caps(cxlds, expected, found, true)) {
> + dev_err(&pdev->dev,
> + "Expected mandatory capabilities not found: (%08lx - %08lx)\n",
> + *expected, *found);
> + return -ENXIO;
> + }
> +
> rc = cxl_pci_type3_init_mailbox(cxlds);
> if (rc)
> return rc;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index dcc9ec8a0aec..ab243ab8024f 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -39,7 +39,7 @@ enum cxl_dev_cap {
> CXL_DEV_CAP_DEV_STATUS,
> CXL_DEV_CAP_MAILBOX_PRIMARY,
> CXL_DEV_CAP_MEMDEV,
> - CXL_MAX_CAPS = 32
> + CXL_MAX_CAPS = 64
> };
>
> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
> @@ -48,4 +48,8 @@ void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
> void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
> int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> enum cxl_resource);
> +bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
> + unsigned long *expected_caps,
> + unsigned long *current_caps,
> + bool is_subset);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 05/27] cxl: move pci generic code
2024-11-18 16:44 ` [PATCH v5 05/27] cxl: move pci generic code alejandro.lucero-palau
2024-11-18 22:57 ` Dave Jiang
@ 2024-11-22 20:44 ` Ben Cheatham
1 sibling, 0 replies; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:44 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Inside cxl/core/pci.c there are helpers for CXL PCIe initialization
> meanwhile cxl/pci.c implements the functionality for a Type3 device
> initialization.
>
> Move helper functions from cxl/pci.c to cxl/core/pci.c in order to be
> exported and shared with CXL Type2 device initialization.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
LGTM,
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> ---
> drivers/cxl/core/pci.c | 62 ++++++++++++++++++++++++++++++++++++++++++
> drivers/cxl/cxlpci.h | 3 ++
> drivers/cxl/pci.c | 58 ---------------------------------------
> 3 files changed, 65 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index a1942b7be0bc..bfc5e96e3cb9 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -1034,6 +1034,68 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
> }
> EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL);
>
> +/*
> + * Assume that any RCIEP that emits the CXL memory expander class code
> + * is an RCD
> + */
> +bool is_cxl_restricted(struct pci_dev *pdev)
> +{
> + return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
> +}
> +EXPORT_SYMBOL_NS_GPL(is_cxl_restricted, CXL);
> +
> +static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
> + struct cxl_register_map *map)
> +{
> + struct cxl_port *port;
> + struct cxl_dport *dport;
> + resource_size_t component_reg_phys;
> +
> + *map = (struct cxl_register_map) {
> + .host = &pdev->dev,
> + .resource = CXL_RESOURCE_NONE,
> + };
> +
> + port = cxl_pci_find_port(pdev, &dport);
> + if (!port)
> + return -EPROBE_DEFER;
> +
> + component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
> +
> + put_device(&port->dev);
> +
> + if (component_reg_phys == CXL_RESOURCE_NONE)
> + return -ENXIO;
> +
> + map->resource = component_reg_phys;
> + map->reg_type = CXL_REGLOC_RBI_COMPONENT;
> + map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
> +
> + return 0;
> +}
> +
> +int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> + struct cxl_register_map *map, unsigned long *caps)
> +{
> + int rc;
> +
> + rc = cxl_find_regblock(pdev, type, map);
> +
> + /*
> + * If the Register Locator DVSEC does not exist, check if it
> + * is an RCH and try to extract the Component Registers from
> + * an RCRB.
> + */
> + if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev))
> + rc = cxl_rcrb_get_comp_regs(pdev, map);
> +
> + if (rc)
> + return rc;
> +
> + return cxl_setup_regs(map, caps);
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, CXL);
> +
> int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
> {
> int speed, bw;
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index eb59019fe5f3..985cca3c3350 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -113,4 +113,7 @@ void read_cdat_data(struct cxl_port *port);
> void cxl_cor_error_detected(struct pci_dev *pdev);
> pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
> pci_channel_state_t state);
> +bool is_cxl_restricted(struct pci_dev *pdev);
> +int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> + struct cxl_register_map *map, unsigned long *caps);
> #endif /* __CXL_PCI_H__ */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 5de1473a79da..caa7e101e063 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -467,64 +467,6 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail)
> return 0;
> }
>
> -/*
> - * Assume that any RCIEP that emits the CXL memory expander class code
> - * is an RCD
> - */
> -static bool is_cxl_restricted(struct pci_dev *pdev)
> -{
> - return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
> -}
> -
> -static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
> - struct cxl_register_map *map)
> -{
> - struct cxl_dport *dport;
> - resource_size_t component_reg_phys;
> -
> - *map = (struct cxl_register_map) {
> - .host = &pdev->dev,
> - .resource = CXL_RESOURCE_NONE,
> - };
> -
> - struct cxl_port *port __free(put_cxl_port) =
> - cxl_pci_find_port(pdev, &dport);
> - if (!port)
> - return -EPROBE_DEFER;
> -
> - component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
> - if (component_reg_phys == CXL_RESOURCE_NONE)
> - return -ENXIO;
> -
> - map->resource = component_reg_phys;
> - map->reg_type = CXL_REGLOC_RBI_COMPONENT;
> - map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
> -
> - return 0;
> -}
> -
> -static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
> - struct cxl_register_map *map,
> - unsigned long *caps)
> -{
> - int rc;
> -
> - rc = cxl_find_regblock(pdev, type, map);
> -
> - /*
> - * If the Register Locator DVSEC does not exist, check if it
> - * is an RCH and try to extract the Component Registers from
> - * an RCRB.
> - */
> - if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev))
> - rc = cxl_rcrb_get_comp_regs(pdev, map);
> -
> - if (rc)
> - return rc;
> -
> - return cxl_setup_regs(map, caps);
> -}
> -
> static int cxl_pci_ras_unmask(struct pci_dev *pdev)
> {
> struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 08/27] cxl: add functions for resource request/release by a driver
2024-11-18 16:44 ` [PATCH v5 08/27] cxl: add functions for resource request/release by a driver alejandro.lucero-palau
@ 2024-11-22 20:45 ` Ben Cheatham
0 siblings, 0 replies; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:45 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Create accessors for an accel driver requesting and releasing a resource.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 2 ++
> 2 files changed, 53 insertions(+)
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index d083fd13a6dd..7450172c1864 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -744,6 +744,57 @@ int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> }
> EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
>
> +int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
> +{
> + int rc;
> +
> + switch (type) {
> + case CXL_RES_RAM:
> + if (!resource_size(&cxlds->ram_res)) {
> + dev_err(cxlds->dev,
> + "resource request for ram with size 0\n");
> + return -EINVAL;
> + }
> +
> + rc = request_resource(&cxlds->dpa_res, &cxlds->ram_res);
> + break;
> + case CXL_RES_PMEM:
> + if (!resource_size(&cxlds->pmem_res)) {
> + dev_err(cxlds->dev,
> + "resource request for pmem with size 0\n");
> + return -EINVAL;
> + }
> + rc = request_resource(&cxlds->dpa_res, &cxlds->pmem_res);
> + break;
> + default:
> + dev_err(cxlds->dev, "unsupported resource type (%u)\n", type);
> + return -EINVAL;
> + }
> +
> + return rc;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_request_resource, CXL);
> +
> +int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
> +{
> + int rc;
> +
> + switch (type) {
> + case CXL_RES_RAM:
> + rc = release_resource(&cxlds->ram_res);
> + break;
> + case CXL_RES_PMEM:
> + rc = release_resource(&cxlds->pmem_res);
> + break;
> + default:
> + dev_err(cxlds->dev, "unknown resource type (%u)\n", type);
> + return -EINVAL;
> + }
> +
> + return rc;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_release_resource, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index a88d3475e551..e0bafd066b93 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -54,4 +54,6 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
> unsigned long *current_caps,
> bool is_subset);
> int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
> +int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> +int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 11/27] cxl: add function for setting media ready by a driver
2024-11-18 16:44 ` [PATCH v5 11/27] cxl: add function for setting media ready by a driver alejandro.lucero-palau
2024-11-19 18:12 ` Dave Jiang
@ 2024-11-22 20:45 ` Ben Cheatham
2024-11-27 15:07 ` Alejandro Lucero Palau
1 sibling, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:45 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> A Type-2 driver can require to set the memory availability explicitly.
Little grammar nit, I think "may be required" reads better. I would also say
why, for example: "... set the memory availability explicitly due to the
possible lack of a mailbox".
>
> Add a function to the exported CXL API for accelerator drivers.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
Actual patch contents LGTM, so regardless of nit above:
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> drivers/cxl/core/memdev.c | 6 ++++++
> include/cxl/cxl.h | 1 +
> 2 files changed, 7 insertions(+)
>
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index 7450172c1864..d746c8a1021c 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -795,6 +795,12 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
> }
> EXPORT_SYMBOL_NS_GPL(cxl_release_resource, CXL);
>
> +void cxl_set_media_ready(struct cxl_dev_state *cxlds)
> +{
> + cxlds->media_ready = true;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_set_media_ready, CXL);
> +
> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> {
> struct cxl_memdev *cxlmd =
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index e0bafd066b93..6033ce84b3d3 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -56,4 +56,5 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
> int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
> int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> +void cxl_set_media_ready(struct cxl_dev_state *cxlds);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-18 16:44 ` [PATCH v5 13/27] cxl: prepare memdev creation for type2 alejandro.lucero-palau
2024-11-19 18:24 ` Dave Jiang
@ 2024-11-22 20:45 ` Ben Cheatham
2024-11-27 16:09 ` Alejandro Lucero Palau
1 sibling, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:45 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, dan.j.williams, martin.habets, edward.cree, davem,
pabeni, edumazet, kuba, netdev, Cheatham, Benjamin
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device when
> creating a memdev leading to problems when obtaining cxl_memdev_state
> references from a CXL_DEVTYPE_DEVMEM type. This last device type is
> managed by a specific vendor driver and does not need same sysfs files
> since not userspace intervention is expected.
>
> Create a new cxl_mem device type with no attributes for Type2.
>
> Avoid debugfs files relying on existence of clx_memdev_state.
>
> Make devm_cxl_add_memdev accesible from a accel driver.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/cdat.c | 3 +++
> drivers/cxl/core/memdev.c | 15 +++++++++++++--
> drivers/cxl/core/region.c | 3 ++-
> drivers/cxl/mem.c | 25 +++++++++++++++++++------
> include/cxl/cxl.h | 2 ++
> 5 files changed, 39 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> index e9cd7939c407..192cff18ea25 100644
> --- a/drivers/cxl/core/cdat.c
> +++ b/drivers/cxl/core/cdat.c
> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle
> struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
> struct cxl_dpa_perf *perf;
>
> + if (!mds)
> + return ERR_PTR(-EINVAL);
> +
> switch (mode) {
> case CXL_DECODER_RAM:
> perf = &mds->ram_perf;
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index d746c8a1021c..df31eea0c06b 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -547,9 +547,17 @@ static const struct device_type cxl_memdev_type = {
> .groups = cxl_memdev_attribute_groups,
> };
>
> +static const struct device_type cxl_accel_memdev_type = {
> + .name = "cxl_memdev",
I would like to see a different name than cxl_memdev here, since this is technically
a different type and I could see it being confusing sysfs-wise. Maybe "cxl_acceldev"
or "cxl_accel_memdev" instead?
> + .release = cxl_memdev_release,
> + .devnode = cxl_memdev_devnode,
> +};
> +
> bool is_cxl_memdev(const struct device *dev)
> {
> - return dev->type == &cxl_memdev_type;
> + return (dev->type == &cxl_memdev_type ||
> + dev->type == &cxl_accel_memdev_type);
> +
> }
> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
>
> @@ -660,7 +668,10 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> dev->parent = cxlds->dev;
> dev->bus = &cxl_bus_type;
> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
> - dev->type = &cxl_memdev_type;
> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
> + dev->type = &cxl_accel_memdev_type;
> + else
> + dev->type = &cxl_memdev_type;
> device_set_pm_not_required(dev);
> INIT_WORK(&cxlmd->detach_work, detach_memdev);
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index dff618c708dc..622e3bb2e04b 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct cxl_region *cxlr,
> return -EINVAL;
> }
>
> - cxl_region_perf_data_calculate(cxlr, cxled);
> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
> + cxl_region_perf_data_calculate(cxlr, cxled);
>
> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
> int i;
> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
> index a9fd5cd5a0d2..cb771bf196cd 100644
> --- a/drivers/cxl/mem.c
> +++ b/drivers/cxl/mem.c
> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
> dentry = cxl_debugfs_create_dir(dev_name(dev));
> debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
>
> - if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
> - debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
> - &cxl_poison_inject_fops);
> - if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
> - debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
> - &cxl_poison_clear_fops);
> + /*
> + * Avoid poison debugfs files for Type2 devices as they rely on
> + * cxl_memdev_state.
> + */
> + if (mds) {
> + if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
> + debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
> + &cxl_poison_inject_fops);
> + if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
> + debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
> + &cxl_poison_clear_fops);
> + }
>
> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
> if (rc)
> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
> struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
> struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
>
> + /*
> + * Avoid poison sysfs files for Type2 devices as they rely on
> + * cxl_memdev_state.
> + */
> + if (!mds)
> + return 0;
cxl_accel_memdev don't use the same attributes, so I imagine this modification isn't needed?
I'm probably just missing something here.
> +
> if (a == &dev_attr_trigger_poison_list.attr)
> if (!test_bit(CXL_POISON_ENABLED_LIST,
> mds->poison.enabled_cmds))
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 6033ce84b3d3..5608ed0f5f15 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
> int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> void cxl_set_media_ready(struct cxl_dev_state *cxlds);
> +struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
> + struct cxl_dev_state *cxlds);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 18/27] sfc: get endpoint decoder
2024-11-18 16:44 ` [PATCH v5 18/27] sfc: get endpoint decoder alejandro.lucero-palau
@ 2024-11-22 20:45 ` Ben Cheatham
2024-11-27 16:47 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:45 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Use cxl api for getting DPA (Device Physical Address) to use through an
> endpoint decoder.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/net/ethernet/sfc/efx_cxl.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> index 048500492371..85d9632f497a 100644
> --- a/drivers/net/ethernet/sfc/efx_cxl.c
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -120,6 +120,14 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> goto err3;
> }
>
> + cxl->cxled = cxl_request_dpa(cxl->cxlmd, true, EFX_CTPIO_BUFFER_SIZE,
> + EFX_CTPIO_BUFFER_SIZE);
> + if (!cxl->cxled || IS_ERR(cxl->cxled)) {
I'm 99% sure you can replace this with IS_ERR_OR_NULL(cxl->cxled).
> + pci_err(pci_dev, "CXL accel request DPA failed");
> + rc = PTR_ERR(cxl->cxlrd);
> + goto err3;
> + }
> +
> probe_data->cxl = cxl;
>
> return 0;
> @@ -137,6 +145,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> void efx_cxl_exit(struct efx_probe_data *probe_data)
> {
> if (probe_data->cxl) {
> + cxl_dpa_free(probe_data->cxl->cxled);
> cxl_release_resource(probe_data->cxl->cxlds, CXL_RES_RAM);
> kfree(probe_data->cxl->cxlds);
> kfree(probe_data->cxl);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration
2024-11-18 16:44 ` [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration alejandro.lucero-palau
@ 2024-11-22 20:45 ` Ben Cheatham
2024-11-27 16:32 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:45 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> CXL region creation involves allocating capacity from device DPA
> (device-physical-address space) and assigning it to decode a given HPA
> (host-physical-address space). Before determining how much DPA to
> allocate the amount of available HPA must be determined. Also, not all
> HPA is create equal, some specifically targets RAM, some target PMEM,
> some is prepared for device-memory flows like HDM-D and HDM-DB, and some
> is host-only (HDM-H).
>
> Wrap all of those concerns into an API that retrieves a root decoder
> (platform CXL window) that fits the specified constraints and the
> capacity available for a new region.
>
> Based on https://lore.kernel.org/linux-cxl/168592159290.1948938.13522227102445462976.stgit@dwillia2-xfh.jf.intel.com/
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/cxl/core/region.c | 141 ++++++++++++++++++++++++++++++++++++++
> drivers/cxl/cxl.h | 3 +
> include/cxl/cxl.h | 8 +++
> 3 files changed, 152 insertions(+)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 622e3bb2e04b..d107cc1b4350 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -687,6 +687,147 @@ static int free_hpa(struct cxl_region *cxlr)
> return 0;
> }
>
> +struct cxlrd_max_context {
> + struct device *host_bridge;
> + unsigned long flags;
> + resource_size_t max_hpa;
> + struct cxl_root_decoder *cxlrd;
> +};
> +
> +static int find_max_hpa(struct device *dev, void *data)
> +{
> + struct cxlrd_max_context *ctx = data;
> + struct cxl_switch_decoder *cxlsd;
> + struct cxl_root_decoder *cxlrd;
> + struct resource *res, *prev;
> + struct cxl_decoder *cxld;
> + resource_size_t max;
> +
> + if (!is_root_decoder(dev))
> + return 0;
> +
> + cxlrd = to_cxl_root_decoder(dev);
> + cxlsd = &cxlrd->cxlsd;
> + cxld = &cxlsd->cxld;
> + if ((cxld->flags & ctx->flags) != ctx->flags) {
> + dev_dbg(dev, "%s, flags not matching: %08lx vs %08lx\n",
> + __func__, cxld->flags, ctx->flags);
> + return 0;
> + }
> +
> + /* An accelerator can not be part of an interleaved HPA range. */
Someone else can weigh in on this, but I would also specify that this is a kernel/driver restriction,
not a spec one.
> + if (cxld->interleave_ways != 1) {
> + dev_dbg(dev, "%s, interleave_ways not matching\n", __func__);
> + return 0;
> + }
> +
> + guard(rwsem_read)(&cxl_region_rwsem);
> + if (ctx->host_bridge != cxlsd->target[0]->dport_dev) {
> + dev_dbg(dev, "%s, host bridge does not match\n", __func__);
> + return 0;
> + }
Is this check necessary? I would imagine that there can only be a single
host bridge above our endpoint since there's also no interleaving?
> +
> + /*
> + * Walk the root decoder resource range relying on cxl_region_rwsem to
> + * preclude sibling arrival/departure and find the largest free space
> + * gap.
> + */
> + lockdep_assert_held_read(&cxl_region_rwsem);
> + max = 0;
> + res = cxlrd->res->child;
> + if (!res)
> + max = resource_size(cxlrd->res);
> + else
> + max = 0;
> +
> + for (prev = NULL; res; prev = res, res = res->sibling) {
> + struct resource *next = res->sibling;
> + resource_size_t free = 0;
> +
> + if (!prev && res->start > cxlrd->res->start) {
> + free = res->start - cxlrd->res->start;
> + max = max(free, max);
> + }
> + if (prev && res->start > prev->end + 1) {
> + free = res->start - prev->end + 1;
> + max = max(free, max);
> + }
> + if (next && res->end + 1 < next->start) {
> + free = next->start - res->end + 1;
> + max = max(free, max);
> + }
> + if (!next && res->end + 1 < cxlrd->res->end + 1) {
> + free = cxlrd->res->end + 1 - res->end + 1;
> + max = max(free, max);
> + }
> + }
> +
> + dev_dbg(CXLRD_DEV(cxlrd), "%s, found %pa bytes of free space\n",
> + __func__, &max);
> + if (max > ctx->max_hpa) {
> + if (ctx->cxlrd)
> + put_device(CXLRD_DEV(ctx->cxlrd));
> + get_device(CXLRD_DEV(cxlrd));
> + ctx->cxlrd = cxlrd;
> + ctx->max_hpa = max;
> + dev_dbg(CXLRD_DEV(cxlrd), "%s, found %pa bytes of free space\n",
> + __func__, &max);
> + }
> + return 0;
> +}
> +
> +/**
> + * cxl_get_hpa_freespace - find a root decoder with free capacity per constraints
> + * @endpoint: an endpoint that is mapped by the returned decoder
> + * @flags: CXL_DECODER_F flags for selecting RAM vs PMEM, and HDM-H vs HDM-D[B]
> + * @max_avail_contig: output parameter of max contiguous bytes available in the
> + * returned decoder
> + *
> + * The return tuple of a 'struct cxl_root_decoder' and 'bytes available (@max)'
The (@max) part should be (@max_avail_contig), no?
> + * is a point in time snapshot. If by the time the caller goes to use this root
> + * decoder's capacity the capacity is reduced then caller needs to loop and
> + * retry.
> + *
> + * The returned root decoder has an elevated reference count that needs to be
> + * put with put_device(cxlrd_dev(cxlrd)). Locking context is with
> + * cxl_{acquire,release}_endpoint(), that ensures removal of the root decoder
> + * does not race.
> + */
> +struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
> + unsigned long flags,
> + resource_size_t *max_avail_contig)
> +{
> + struct cxl_port *endpoint = cxlmd->endpoint;
> + struct cxlrd_max_context ctx = {
> + .host_bridge = endpoint->host_bridge,
> + .flags = flags,
> + };
> + struct cxl_port *root_port;
> + struct cxl_root *root __free(put_cxl_root) = find_cxl_root(endpoint);
> +
> + if (!is_cxl_endpoint(endpoint)) {
> + dev_dbg(&endpoint->dev, "hpa requestor is not an endpoint\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (!root) {
> + dev_dbg(&endpoint->dev, "endpoint can not be related to a root port\n");
This message makes it seem like there's a problem with the endpoint, not the hierarchy (at least to me).
Maybe something like "can't find root port associated with endpoint" or "can't find root port above endpoint" instead?
> + return ERR_PTR(-ENXIO);
> + }
> +
> + root_port = &root->port;
> + down_read(&cxl_region_rwsem);
> + device_for_each_child(&root_port->dev, &ctx, find_max_hpa);
> + up_read(&cxl_region_rwsem);
> +
> + if (!ctx.cxlrd)
> + return ERR_PTR(-ENOMEM);
> +
> + *max_avail_contig = ctx.max_hpa;
> + return ctx.cxlrd;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_hpa_freespace, CXL);
> +
> static ssize_t size_store(struct device *dev, struct device_attribute *attr,
> const char *buf, size_t len)
> {
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index e5f918be6fe4..1e0e797b9303 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -776,6 +776,9 @@ static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport,
> struct cxl_decoder *to_cxl_decoder(struct device *dev);
> struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
> struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev);
> +
> +#define CXLRD_DEV(cxlrd) (&(cxlrd)->cxlsd.cxld.dev)
> +
> struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
> bool is_root_decoder(struct device *dev);
> bool is_switch_decoder(struct device *dev);
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 5608ed0f5f15..4508b5c186e8 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -7,6 +7,10 @@
> #include <linux/ioport.h>
> #include <linux/pci.h>
>
> +#define CXL_DECODER_F_RAM BIT(0)
> +#define CXL_DECODER_F_PMEM BIT(1)
> +#define CXL_DECODER_F_TYPE2 BIT(2)
> +
> enum cxl_resource {
> CXL_RES_DPA,
> CXL_RES_RAM,
> @@ -59,4 +63,8 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
> void cxl_set_media_ready(struct cxl_dev_state *cxlds);
> struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
> struct cxl_dev_state *cxlds);
> +struct cxl_port;
> +struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
> + unsigned long flags,
> + resource_size_t *max);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax
2024-11-18 16:44 ` [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax alejandro.lucero-palau
2024-11-19 20:39 ` Zhi Wang
@ 2024-11-22 20:46 ` Ben Cheatham
2024-11-27 16:59 ` Alejandro Lucero Palau
1 sibling, 1 reply; 99+ messages in thread
From: Ben Cheatham @ 2024-11-22 20:46 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> By definition a type2 cxl device will use the host managed memory for
> specific functionality, therefore it should not be available to other
> uses. However, a dax interface could be just good enough in some cases.
>
> Add a flag to a cxl region for specifically state to not create a dax
> device. Allow a Type2 driver to set that flag at region creation time.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/region.c | 10 +++++++++-
> drivers/cxl/cxl.h | 3 +++
> drivers/cxl/cxlmem.h | 3 ++-
> include/cxl/cxl.h | 3 ++-
> 4 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 70549d42c2e3..eff3ad788077 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -3558,7 +3558,8 @@ __construct_new_region(struct cxl_root_decoder *cxlrd,
> * cxl_region driver.
> */
> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled)
> + struct cxl_endpoint_decoder *cxled,
> + bool avoid_dax)
> {
> struct cxl_region *cxlr;
>
> @@ -3574,6 +3575,10 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> drop_region(cxlr);
> return ERR_PTR(-ENODEV);
> }
> +
> + if (avoid_dax)
> + set_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags);
> +
> return cxlr;
> }
> EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
> @@ -3713,6 +3718,9 @@ static int cxl_region_probe(struct device *dev)
> case CXL_DECODER_PMEM:
> return devm_cxl_add_pmem_region(cxlr);
> case CXL_DECODER_RAM:
> + if (test_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags))
> + return 0;
I think it's possible for a type 2 device to have pmem as well, and
it looks like these are the only two options at the moment, so I would
just move this check to before the switch statement.
> +
> /*
> * The region can not be manged by CXL if any portion of
> * it is already online as 'System RAM'
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 1e0e797b9303..ee3385db5663 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -512,6 +512,9 @@ struct cxl_region_params {
> */
> #define CXL_REGION_F_NEEDS_RESET 1
>
> +/* Allow Type2 drivers to specify if a dax region should not be created. */
> +#define CXL_REGION_F_AVOID_DAX 2
> +
I would like to see flags such that the device could choose the region type
(system ram, device-dax, or none). I think that adding the ability
for device-dax would add a patch or two, so that may be a good follow up
patch.
> /**
> * struct cxl_region - CXL region
> * @dev: This region's device
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 9d874f1cb3bf..cc2e2a295f3d 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -875,5 +875,6 @@ struct seq_file;
> struct dentry *cxl_debugfs_create_dir(const char *dir);
> void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled);
> + struct cxl_endpoint_decoder *cxled,
> + bool avoid_dax);
> #endif /* __CXL_MEM_H__ */
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index d295af4f5f9e..2a8ebabfc1dd 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -73,7 +73,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
> resource_size_t max);
> int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
> - struct cxl_endpoint_decoder *cxled);
> + struct cxl_endpoint_decoder *cxled,
> + bool avoid_dax);
>
> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-22 9:27 ` Alejandro Lucero Palau
@ 2024-11-26 5:59 ` Alison Schofield
2024-11-26 16:38 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Alison Schofield @ 2024-11-26 5:59 UTC (permalink / raw)
To: Alejandro Lucero Palau
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On Fri, Nov 22, 2024 at 09:27:34AM +0000, Alejandro Lucero Palau wrote:
>
> On 11/22/24 04:35, Alison Schofield wrote:
> > On Mon, Nov 18, 2024 at 04:44:08PM +0000, alejandro.lucero-palau@amd.com wrote:
> > > From: Alejandro Lucero <alucerop@amd.com>
> > >
> > > Differentiate Type3, aka memory expanders, from Type2, aka device
> > > accelerators, with a new function for initializing cxl_dev_state.
> > >
> > > Create accessors to cxl_dev_state to be used by accel drivers.
> > >
> > > Based on previous work by Dan Williams [1]
> > >
> > > Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
> > > Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> > > Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> > > ---
> > > drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
> > > drivers/cxl/core/pci.c | 1 +
> > > drivers/cxl/cxlpci.h | 16 ------------
> > > drivers/cxl/pci.c | 13 +++++++---
> > > include/cxl/cxl.h | 21 ++++++++++++++++
> > As I mentioned in the cover letter, beginning w the first patch
> > I have depmod issues building with the cxl-test module. I didn't
> > get very far figuring it out, other than a work-around of moving
> > the contents of include/cxl/cxl.h down into drivers/cxl/cxlmem.h.
> > That band-aid got me a bit further. In fact I wasn't so concerned
> > with breaking sfx as I was with regression testing the changes to
> > drivers/cxl/.
> >
> > Please see if you can get the cxl-test module working again.
>
>
> Hi Allison,
>
>
> I have no problems building tools/testing/cxl and I can see cxl_test.ko in
> tools/testing/cxl/test
>
Yes that's the one. It builds it just won't load because of the
circular dependency. Sorry I haven't been able to dig into it
further. I use run_qemu.sh [1] which uses mkosi to build the image.
It fails at the depmod step and I haven't been able to dig further.
depmod: ERROR: Cycle detected: cxl_mock -> cxl_core -> cxl_mock
depmod: ERROR: Found 2 modules in dependency cycles!
So, I'd expect it would fail at make modules_intall for you.
BTW - this happens occasionally, but usually on a smaller scale,
ie we know exactly what just changed. I suspect it happens with
only Patch 1 applied - but even limiting it to that I could not
nail it down.
--Alison
[1] https://github.com/pmem/run_qemu
>
> I did try with the full patchset applied over 6.12-rc7 tag, and also with
> only the first patch since I was not sure if you meant the build after each
> patch is tried, but both worked once I modified the config for the checks
> inside config_check.c not to fail.
>
>
> I guess you meant this cxl test and not the one related to "git clone
> https://github.com/moking/cxl-test-tool.git" what I have no experience with.
no
>
>
> Could someone else try this as well?
>
>
> >
> > > include/cxl/pci.h | 23 ++++++++++++++++++
> > > 6 files changed, 105 insertions(+), 20 deletions(-)
> > > create mode 100644 include/cxl/cxl.h
> > > create mode 100644 include/cxl/pci.h
> > >
> > > diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> > > index 84fefb76dafa..d083fd13a6dd 100644
> > > --- a/drivers/cxl/core/memdev.c
> > > +++ b/drivers/cxl/core/memdev.c
> > > @@ -1,6 +1,7 @@
> > > // SPDX-License-Identifier: GPL-2.0-only
> > > /* Copyright(c) 2020 Intel Corporation. */
> > > +#include <cxl/cxl.h>
> > > #include <linux/io-64-nonatomic-lo-hi.h>
> > > #include <linux/firmware.h>
> > > #include <linux/device.h>
> > > @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
> > > static struct lock_class_key cxl_memdev_key;
> > > +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
> > > +{
> > > + struct cxl_dev_state *cxlds;
> > > +
> > > + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
> > > + if (!cxlds)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + cxlds->dev = dev;
> > > + cxlds->type = CXL_DEVTYPE_DEVMEM;
> > > +
> > > + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
> > > + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
> > > + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
> > > +
> > > + return cxlds;
> > > +}
> > > +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
> > > +
> > > static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
> > > const struct file_operations *fops)
> > > {
> > > @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
> > > return 0;
> > > }
> > > +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
> > > +{
> > > + cxlds->cxl_dvsec = dvsec;
> > > +}
> > > +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
> > > +
> > > +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
> > > +{
> > > + cxlds->serial = serial;
> > > +}
> > > +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
> > > +
> > > +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> > > + enum cxl_resource type)
> > > +{
> > > + switch (type) {
> > > + case CXL_RES_DPA:
> > > + cxlds->dpa_res = res;
> > > + return 0;
> > > + case CXL_RES_RAM:
> > > + cxlds->ram_res = res;
> > > + return 0;
> > > + case CXL_RES_PMEM:
> > > + cxlds->pmem_res = res;
> > > + return 0;
> > > + }
> > > +
> > > + return -EINVAL;
> > > +}
> > > +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
> > > +
> > > static int cxl_memdev_release_file(struct inode *inode, struct file *file)
> > > {
> > > struct cxl_memdev *cxlmd =
> > > diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> > > index 420e4be85a1f..ff266e91ea71 100644
> > > --- a/drivers/cxl/core/pci.c
> > > +++ b/drivers/cxl/core/pci.c
> > > @@ -1,5 +1,6 @@
> > > // SPDX-License-Identifier: GPL-2.0-only
> > > /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
> > > +#include <cxl/pci.h>
> > > #include <linux/units.h>
> > > #include <linux/io-64-nonatomic-lo-hi.h>
> > > #include <linux/device.h>
> > > diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> > > index 4da07727ab9c..eb59019fe5f3 100644
> > > --- a/drivers/cxl/cxlpci.h
> > > +++ b/drivers/cxl/cxlpci.h
> > > @@ -14,22 +14,6 @@
> > > */
> > > #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
> > > -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> > > -#define CXL_DVSEC_PCIE_DEVICE 0
> > > -#define CXL_DVSEC_CAP_OFFSET 0xA
> > > -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> > > -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> > > -#define CXL_DVSEC_CTRL_OFFSET 0xC
> > > -#define CXL_DVSEC_MEM_ENABLE BIT(2)
> > > -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
> > > -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
> > > -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> > > -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> > > -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> > > -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
> > > -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
> > > -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> > > -
> > > #define CXL_DVSEC_RANGE_MAX 2
> > > /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
> > > diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> > > index 188412d45e0d..0b910ef52db7 100644
> > > --- a/drivers/cxl/pci.c
> > > +++ b/drivers/cxl/pci.c
> > > @@ -1,5 +1,7 @@
> > > // SPDX-License-Identifier: GPL-2.0-only
> > > /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> > > +#include <cxl/cxl.h>
> > > +#include <cxl/pci.h>
> > > #include <linux/unaligned.h>
> > > #include <linux/io-64-nonatomic-lo-hi.h>
> > > #include <linux/moduleparam.h>
> > > @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> > > struct cxl_memdev *cxlmd;
> > > int i, rc, pmu_count;
> > > bool irq_avail;
> > > + u16 dvsec;
> > > /*
> > > * Double check the anonymous union trickery in struct cxl_regs
> > > @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> > > pci_set_drvdata(pdev, cxlds);
> > > cxlds->rcd = is_cxl_restricted(pdev);
> > > - cxlds->serial = pci_get_dsn(pdev);
> > > - cxlds->cxl_dvsec = pci_find_dvsec_capability(
> > > - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
> > > - if (!cxlds->cxl_dvsec)
> > > + cxl_set_serial(cxlds, pci_get_dsn(pdev));
> > > + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
> > > + CXL_DVSEC_PCIE_DEVICE);
> > > + if (!dvsec)
> > > dev_warn(&pdev->dev,
> > > "Device DVSEC not present, skip CXL.mem init\n");
> > > + cxl_set_dvsec(cxlds, dvsec);
> > > +
> > > rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
> > > if (rc)
> > > return rc;
> > > diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> > > new file mode 100644
> > > index 000000000000..19e5d883557a
> > > --- /dev/null
> > > +++ b/include/cxl/cxl.h
> > > @@ -0,0 +1,21 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
> > > +
> > > +#ifndef __CXL_H
> > > +#define __CXL_H
> > > +
> > > +#include <linux/ioport.h>
> > > +
> > > +enum cxl_resource {
> > > + CXL_RES_DPA,
> > > + CXL_RES_RAM,
> > > + CXL_RES_PMEM,
> > > +};
> > > +
> > > +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
> > > +
> > > +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
> > > +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
> > > +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
> > > + enum cxl_resource);
> > > +#endif
> > > diff --git a/include/cxl/pci.h b/include/cxl/pci.h
> > > new file mode 100644
> > > index 000000000000..ad63560caa2c
> > > --- /dev/null
> > > +++ b/include/cxl/pci.h
> > > @@ -0,0 +1,23 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> > > +
> > > +#ifndef __CXL_ACCEL_PCI_H
> > > +#define __CXL_ACCEL_PCI_H
> > > +
> > > +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
> > > +#define CXL_DVSEC_PCIE_DEVICE 0
> > > +#define CXL_DVSEC_CAP_OFFSET 0xA
> > > +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
> > > +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
> > > +#define CXL_DVSEC_CTRL_OFFSET 0xC
> > > +#define CXL_DVSEC_MEM_ENABLE BIT(2)
> > > +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
> > > +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
> > > +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
> > > +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
> > > +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
> > > +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
> > > +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
> > > +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
> > > +
> > > +#endif
> > > --
> > > 2.17.1
> > >
> > >
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-26 5:59 ` Alison Schofield
@ 2024-11-26 16:38 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-26 16:38 UTC (permalink / raw)
To: Alison Schofield
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On 11/26/24 05:59, Alison Schofield wrote:
> On Fri, Nov 22, 2024 at 09:27:34AM +0000, Alejandro Lucero Palau wrote:
>> On 11/22/24 04:35, Alison Schofield wrote:
>>> On Mon, Nov 18, 2024 at 04:44:08PM +0000, alejandro.lucero-palau@amd.com wrote:
>>>> From: Alejandro Lucero <alucerop@amd.com>
>>>>
>>>> Differentiate Type3, aka memory expanders, from Type2, aka device
>>>> accelerators, with a new function for initializing cxl_dev_state.
>>>>
>>>> Create accessors to cxl_dev_state to be used by accel drivers.
>>>>
>>>> Based on previous work by Dan Williams [1]
>>>>
>>>> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
>>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>>> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
>>>> ---
>>>> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
>>>> drivers/cxl/core/pci.c | 1 +
>>>> drivers/cxl/cxlpci.h | 16 ------------
>>>> drivers/cxl/pci.c | 13 +++++++---
>>>> include/cxl/cxl.h | 21 ++++++++++++++++
>>> As I mentioned in the cover letter, beginning w the first patch
>>> I have depmod issues building with the cxl-test module. I didn't
>>> get very far figuring it out, other than a work-around of moving
>>> the contents of include/cxl/cxl.h down into drivers/cxl/cxlmem.h.
>>> That band-aid got me a bit further. In fact I wasn't so concerned
>>> with breaking sfx as I was with regression testing the changes to
>>> drivers/cxl/.
>>>
>>> Please see if you can get the cxl-test module working again.
>>
>> Hi Allison,
>>
>>
>> I have no problems building tools/testing/cxl and I can see cxl_test.ko in
>> tools/testing/cxl/test
>>
> Yes that's the one. It builds it just won't load because of the
> circular dependency. Sorry I haven't been able to dig into it
> further. I use run_qemu.sh [1] which uses mkosi to build the image.
> It fails at the depmod step and I haven't been able to dig further.
>
> depmod: ERROR: Cycle detected: cxl_mock -> cxl_core -> cxl_mock
> depmod: ERROR: Found 2 modules in dependency cycles!
>
> So, I'd expect it would fail at make modules_intall for you.
Linus's tree with 6.12 tag works fine for me. I'm doing it manually,
creating the modules inside tools/testing/cxl and copying them to
/lib/modules/6.12.0/kernel/drivers/cxl replacing the default cxl kernel
modules by these with the testing stuff, and copying there the modules
inside tools/testing/cxl/test where cxl_mock.ko and cxl_test.ko are.
Depmod works fine after that and I can use that kernel+modules loading
cxl_test.ko and cxl_mock.ko without any issue.
I have problems with the cxl next tree and the current Linux's tree
uptodate, with some error when installing modules but not related to
this problem you report.
IMO, it seems it is a problem with the cxl testing code itself, or the
build, because I can not see a reason for the cxl_core depending on
cxl_mock except for those changes introduced for testing. I have been
all day moving from one tree to another and doing tests, so I leave this
to someone familiar with the mock testing sources. BTW, I think all this
should be documented along with the CXL tree to work with. I know there
are instructions in that cxl-test-tool repo but it should be a reference
in cxl.docs.kernel.org about it.
>
> BTW - this happens occasionally, but usually on a smaller scale,
> ie we know exactly what just changed. I suspect it happens with
> only Patch 1 applied - but even limiting it to that I could not
> nail it down.
>
> --Alison
>
>
> [1] https://github.com/pmem/run_qemu
>
>> I did try with the full patchset applied over 6.12-rc7 tag, and also with
>> only the first patch since I was not sure if you meant the build after each
>> patch is tried, but both worked once I modified the config for the checks
>> inside config_check.c not to fail.
>>
>>
>> I guess you meant this cxl test and not the one related to "git clone
>> https://github.com/moking/cxl-test-tool.git" what I have no experience with.
> no
>
>
>
>>
>> Could someone else try this as well?
>>
>>
>>>> include/cxl/pci.h | 23 ++++++++++++++++++
>>>> 6 files changed, 105 insertions(+), 20 deletions(-)
>>>> create mode 100644 include/cxl/cxl.h
>>>> create mode 100644 include/cxl/pci.h
>>>>
>>>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>>>> index 84fefb76dafa..d083fd13a6dd 100644
>>>> --- a/drivers/cxl/core/memdev.c
>>>> +++ b/drivers/cxl/core/memdev.c
>>>> @@ -1,6 +1,7 @@
>>>> // SPDX-License-Identifier: GPL-2.0-only
>>>> /* Copyright(c) 2020 Intel Corporation. */
>>>> +#include <cxl/cxl.h>
>>>> #include <linux/io-64-nonatomic-lo-hi.h>
>>>> #include <linux/firmware.h>
>>>> #include <linux/device.h>
>>>> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>>>> static struct lock_class_key cxl_memdev_key;
>>>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
>>>> +{
>>>> + struct cxl_dev_state *cxlds;
>>>> +
>>>> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
>>>> + if (!cxlds)
>>>> + return ERR_PTR(-ENOMEM);
>>>> +
>>>> + cxlds->dev = dev;
>>>> + cxlds->type = CXL_DEVTYPE_DEVMEM;
>>>> +
>>>> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
>>>> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
>>>> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
>>>> +
>>>> + return cxlds;
>>>> +}
>>>> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
>>>> +
>>>> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
>>>> const struct file_operations *fops)
>>>> {
>>>> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
>>>> return 0;
>>>> }
>>>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
>>>> +{
>>>> + cxlds->cxl_dvsec = dvsec;
>>>> +}
>>>> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
>>>> +
>>>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
>>>> +{
>>>> + cxlds->serial = serial;
>>>> +}
>>>> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
>>>> +
>>>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>>>> + enum cxl_resource type)
>>>> +{
>>>> + switch (type) {
>>>> + case CXL_RES_DPA:
>>>> + cxlds->dpa_res = res;
>>>> + return 0;
>>>> + case CXL_RES_RAM:
>>>> + cxlds->ram_res = res;
>>>> + return 0;
>>>> + case CXL_RES_PMEM:
>>>> + cxlds->pmem_res = res;
>>>> + return 0;
>>>> + }
>>>> +
>>>> + return -EINVAL;
>>>> +}
>>>> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
>>>> +
>>>> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
>>>> {
>>>> struct cxl_memdev *cxlmd =
>>>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
>>>> index 420e4be85a1f..ff266e91ea71 100644
>>>> --- a/drivers/cxl/core/pci.c
>>>> +++ b/drivers/cxl/core/pci.c
>>>> @@ -1,5 +1,6 @@
>>>> // SPDX-License-Identifier: GPL-2.0-only
>>>> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
>>>> +#include <cxl/pci.h>
>>>> #include <linux/units.h>
>>>> #include <linux/io-64-nonatomic-lo-hi.h>
>>>> #include <linux/device.h>
>>>> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
>>>> index 4da07727ab9c..eb59019fe5f3 100644
>>>> --- a/drivers/cxl/cxlpci.h
>>>> +++ b/drivers/cxl/cxlpci.h
>>>> @@ -14,22 +14,6 @@
>>>> */
>>>> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>>>> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>>>> -#define CXL_DVSEC_PCIE_DEVICE 0
>>>> -#define CXL_DVSEC_CAP_OFFSET 0xA
>>>> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>>>> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>>>> -#define CXL_DVSEC_CTRL_OFFSET 0xC
>>>> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
>>>> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
>>>> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
>>>> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>>>> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>>>> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>>>> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
>>>> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
>>>> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>>>> -
>>>> #define CXL_DVSEC_RANGE_MAX 2
>>>> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
>>>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>>>> index 188412d45e0d..0b910ef52db7 100644
>>>> --- a/drivers/cxl/pci.c
>>>> +++ b/drivers/cxl/pci.c
>>>> @@ -1,5 +1,7 @@
>>>> // SPDX-License-Identifier: GPL-2.0-only
>>>> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>>>> +#include <cxl/cxl.h>
>>>> +#include <cxl/pci.h>
>>>> #include <linux/unaligned.h>
>>>> #include <linux/io-64-nonatomic-lo-hi.h>
>>>> #include <linux/moduleparam.h>
>>>> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>>> struct cxl_memdev *cxlmd;
>>>> int i, rc, pmu_count;
>>>> bool irq_avail;
>>>> + u16 dvsec;
>>>> /*
>>>> * Double check the anonymous union trickery in struct cxl_regs
>>>> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>>> pci_set_drvdata(pdev, cxlds);
>>>> cxlds->rcd = is_cxl_restricted(pdev);
>>>> - cxlds->serial = pci_get_dsn(pdev);
>>>> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
>>>> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
>>>> - if (!cxlds->cxl_dvsec)
>>>> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
>>>> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
>>>> + CXL_DVSEC_PCIE_DEVICE);
>>>> + if (!dvsec)
>>>> dev_warn(&pdev->dev,
>>>> "Device DVSEC not present, skip CXL.mem init\n");
>>>> + cxl_set_dvsec(cxlds, dvsec);
>>>> +
>>>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>>>> if (rc)
>>>> return rc;
>>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>>> new file mode 100644
>>>> index 000000000000..19e5d883557a
>>>> --- /dev/null
>>>> +++ b/include/cxl/cxl.h
>>>> @@ -0,0 +1,21 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
>>>> +
>>>> +#ifndef __CXL_H
>>>> +#define __CXL_H
>>>> +
>>>> +#include <linux/ioport.h>
>>>> +
>>>> +enum cxl_resource {
>>>> + CXL_RES_DPA,
>>>> + CXL_RES_RAM,
>>>> + CXL_RES_PMEM,
>>>> +};
>>>> +
>>>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>>>> +
>>>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>>>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
>>>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>>>> + enum cxl_resource);
>>>> +#endif
>>>> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
>>>> new file mode 100644
>>>> index 000000000000..ad63560caa2c
>>>> --- /dev/null
>>>> +++ b/include/cxl/pci.h
>>>> @@ -0,0 +1,23 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>>> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>>>> +
>>>> +#ifndef __CXL_ACCEL_PCI_H
>>>> +#define __CXL_ACCEL_PCI_H
>>>> +
>>>> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>>>> +#define CXL_DVSEC_PCIE_DEVICE 0
>>>> +#define CXL_DVSEC_CAP_OFFSET 0xA
>>>> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>>>> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>>>> +#define CXL_DVSEC_CTRL_OFFSET 0xC
>>>> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
>>>> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
>>>> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
>>>> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>>>> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>>>> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>>>> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
>>>> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
>>>> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>>>> +
>>>> +#endif
>>>> --
>>>> 2.17.1
>>>>
>>>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 02/27] sfc: add cxl support using new CXL API
2024-11-18 16:44 ` [PATCH v5 02/27] sfc: add cxl support using new CXL API alejandro.lucero-palau
2024-11-22 20:43 ` Ben Cheatham
@ 2024-11-26 18:08 ` Fan Ni
2024-11-27 9:17 ` Alejandro Lucero Palau
1 sibling, 1 reply; 99+ messages in thread
From: Fan Ni @ 2024-11-26 18:08 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Alejandro Lucero
On Mon, Nov 18, 2024 at 04:44:09PM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Add CXL initialization based on new CXL API for accel drivers and make
> it dependable on kernel CXL configuration.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/net/ethernet/sfc/Kconfig | 7 +++
> drivers/net/ethernet/sfc/Makefile | 1 +
> drivers/net/ethernet/sfc/efx.c | 24 +++++++-
> drivers/net/ethernet/sfc/efx_cxl.c | 88 +++++++++++++++++++++++++++
> drivers/net/ethernet/sfc/efx_cxl.h | 28 +++++++++
> drivers/net/ethernet/sfc/net_driver.h | 10 +++
> 6 files changed, 157 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
...
> + res = DEFINE_RES_MEM_NAMED(0, EFX_CTPIO_BUFFER_SIZE, "ram");
> + if (cxl_set_resource(cxl->cxlds, res, CXL_RES_RAM)) {
> + pci_err(pci_dev, "cxl_set_resource RAM failed\n");
> + rc = -EINVAL;
> + goto err2;
> + }
> +
> + probe_data->cxl = cxl;
> +
> + return 0;
> +
> +err2:
> + kfree(cxl->cxlds);
> +err1:
> + kfree(cxl);
> + return rc;
> +
Unwanted blank line here.
Fan
> +}
> +
> +void efx_cxl_exit(struct efx_probe_data *probe_data)
> +{
> + if (probe_data->cxl) {
> + kfree(probe_data->cxl->cxlds);
> + kfree(probe_data->cxl);
> + }
> +}
> +
> +MODULE_IMPORT_NS(CXL);
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
> new file mode 100644
> index 000000000000..90fa46bc94db
> --- /dev/null
> +++ b/drivers/net/ethernet/sfc/efx_cxl.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/****************************************************************************
> + * Driver for AMD network controllers and boards
> + * Copyright (C) 2024, Advanced Micro Devices, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation, incorporated herein by reference.
> + */
> +
> +#ifndef EFX_CXL_H
> +#define EFX_CXL_H
> +
> +struct efx_nic;
> +
> +struct efx_cxl {
> + struct cxl_dev_state *cxlds;
> + struct cxl_memdev *cxlmd;
> + struct cxl_root_decoder *cxlrd;
> + struct cxl_port *endpoint;
> + struct cxl_endpoint_decoder *cxled;
> + struct cxl_region *efx_region;
> + void __iomem *ctpio_cxl;
> +};
> +
> +int efx_cxl_init(struct efx_probe_data *probe_data);
> +void efx_cxl_exit(struct efx_probe_data *probe_data);
> +#endif
> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
> index b85c51cbe7f9..efc6d90380b9 100644
> --- a/drivers/net/ethernet/sfc/net_driver.h
> +++ b/drivers/net/ethernet/sfc/net_driver.h
> @@ -1160,14 +1160,24 @@ struct efx_nic {
> atomic_t n_rx_noskb_drops;
> };
>
> +#ifdef CONFIG_SFC_CXL
> +struct efx_cxl;
> +#endif
> +
> /**
> * struct efx_probe_data - State after hardware probe
> * @pci_dev: The PCI device
> * @efx: Efx NIC details
> + * @cxl: details of related cxl objects
> + * @cxl_pio_initialised: cxl initialization outcome.
> */
> struct efx_probe_data {
> struct pci_dev *pci_dev;
> struct efx_nic efx;
> +#ifdef CONFIG_SFC_CXL
> + struct efx_cxl *cxl;
> + bool cxl_pio_initialised;
> +#endif
> };
>
> static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
> --
> 2.17.1
>
--
Fan Ni (From gmail)
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-22 20:43 ` Ben Cheatham
@ 2024-11-27 9:00 ` Alejandro Lucero Palau
2024-11-27 9:07 ` Alejandro Lucero Palau
0 siblings, 1 reply; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 9:00 UTC (permalink / raw)
To: Ben Cheatham, Lucero Palau, Alejandro
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/22/24 20:43, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Differentiate Type3, aka memory expanders, from Type2, aka device
>> accelerators, with a new function for initializing cxl_dev_state.
>>
>> Create accessors to cxl_dev_state to be used by accel drivers.
>>
>> Based on previous work by Dan Williams [1]
>>
>> Link: [1] https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
>> ---
>> drivers/cxl/core/memdev.c | 51 +++++++++++++++++++++++++++++++++++++++
>> drivers/cxl/core/pci.c | 1 +
>> drivers/cxl/cxlpci.h | 16 ------------
>> drivers/cxl/pci.c | 13 +++++++---
>> include/cxl/cxl.h | 21 ++++++++++++++++
>> include/cxl/pci.h | 23 ++++++++++++++++++
>> 6 files changed, 105 insertions(+), 20 deletions(-)
>> create mode 100644 include/cxl/cxl.h
>> create mode 100644 include/cxl/pci.h
>>
>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>> index 84fefb76dafa..d083fd13a6dd 100644
>> --- a/drivers/cxl/core/memdev.c
>> +++ b/drivers/cxl/core/memdev.c
>> @@ -1,6 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2020 Intel Corporation. */
>>
>> +#include <cxl/cxl.h>
> Pedantic one, you'll want this at the end CXL does reverse christmas tree
> for #includes.
That seems to be true for this file, but the reverse christmas tree is
not applied through all the files in the cxl directory.
I was told to put it in alphabetical order (not remember which specific
file), what implies there is no agreement about how to put the header
references.
Anyway, I think for this one your suggestion makes sense.
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/firmware.h>
>> #include <linux/device.h>
>> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct *work)
>>
>> static struct lock_class_key cxl_memdev_key;
>>
>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
>> +{
>> + struct cxl_dev_state *cxlds;
>> +
>> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
> Would it be better to use a devm_kzalloc() here? I'd imagine this function
> will be called as part of probe a majority of the time so I think the automatic
> cleanup would be nice here. If you did that, then I'd also rename the function to
> include devm_ as well.
This is complicated. As I have said in other previous reviews regarding
use of devm_* by the sfc changes in this patchset, it is not advice to
use them inside the netdev subsystem. This is not the case here since it
is cxl code, but in this case used by a netdev client (although other
clients from other subsystems will likely come soon).
So, I'm not sure about this one. I could add the specific function to
use when released like when cxl_memdev_alloc is used by
devm_cxl_add_memdev, but frankly, mixing devm with no devm allocations
is a mess, at least in my view.
>> + if (!cxlds)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + cxlds->dev = dev;
>> + cxlds->type = CXL_DEVTYPE_DEVMEM;
>> +
>> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
>> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
>> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
>> +
>> + return cxlds;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
>> +
>> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
>> const struct file_operations *fops)
>> {
>> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode, struct file *file)
>> return 0;
>> }
>>
>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
>> +{
>> + cxlds->cxl_dvsec = dvsec;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
>> +
>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
>> +{
>> + cxlds->serial = serial;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
>> +
>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> + enum cxl_resource type)
>> +{
>> + switch (type) {
>> + case CXL_RES_DPA:
>> + cxlds->dpa_res = res;
>> + return 0;
>> + case CXL_RES_RAM:
>> + cxlds->ram_res = res;
>> + return 0;
>> + case CXL_RES_PMEM:
>> + cxlds->pmem_res = res;
>> + return 0;
>> + }
>> +
>> + return -EINVAL;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
>> +
>> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
>> {
>> struct cxl_memdev *cxlmd =
>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
>> index 420e4be85a1f..ff266e91ea71 100644
>> --- a/drivers/cxl/core/pci.c
>> +++ b/drivers/cxl/core/pci.c
>> @@ -1,5 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
>> +#include <cxl/pci.h>
>> #include <linux/units.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/device.h>
>> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
>> index 4da07727ab9c..eb59019fe5f3 100644
>> --- a/drivers/cxl/cxlpci.h
>> +++ b/drivers/cxl/cxlpci.h
>> @@ -14,22 +14,6 @@
>> */
>> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>>
>> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>> -#define CXL_DVSEC_PCIE_DEVICE 0
>> -#define CXL_DVSEC_CAP_OFFSET 0xA
>> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>> -#define CXL_DVSEC_CTRL_OFFSET 0xC
>> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
>> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
>> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
>> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
>> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
>> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>> -
>> #define CXL_DVSEC_RANGE_MAX 2
>>
>> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>> index 188412d45e0d..0b910ef52db7 100644
>> --- a/drivers/cxl/pci.c
>> +++ b/drivers/cxl/pci.c
>> @@ -1,5 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>> +#include <cxl/cxl.h>
>> +#include <cxl/pci.h>
>> #include <linux/unaligned.h>
>> #include <linux/io-64-nonatomic-lo-hi.h>
>> #include <linux/moduleparam.h>
>> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> struct cxl_memdev *cxlmd;
>> int i, rc, pmu_count;
>> bool irq_avail;
>> + u16 dvsec;
>>
>> /*
>> * Double check the anonymous union trickery in struct cxl_regs
>> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> pci_set_drvdata(pdev, cxlds);
>>
>> cxlds->rcd = is_cxl_restricted(pdev);
>> - cxlds->serial = pci_get_dsn(pdev);
>> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
>> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
>> - if (!cxlds->cxl_dvsec)
>> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
>> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
>> + CXL_DVSEC_PCIE_DEVICE);
>> + if (!dvsec)
>> dev_warn(&pdev->dev,
>> "Device DVSEC not present, skip CXL.mem init\n");
>>
>> + cxl_set_dvsec(cxlds, dvsec);
>> +
>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>> if (rc)
>> return rc;
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> new file mode 100644
>> index 000000000000..19e5d883557a
>> --- /dev/null
>> +++ b/include/cxl/cxl.h
> Is cxl.h the right name for this file? I initially thought this was the cxl.h
> under drivers/cxl. It looks like it's just type 2 related functions, so maybe
> "type2.h", or "accel.h" would be better? If the plan is to expose more CXL
> functionality not necessarily related to type 2 devices later I'm fine with it,
> and if no one else cares then I'm fine with it.
I agree, but I did use cxl_accel_* in version 2 and it was suggested
then to remove the accel part, so leaving it as it is now if none else
cares about it.
Thanks!
>
>> @@ -0,0 +1,21 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
>> +
>> +#ifndef __CXL_H
>> +#define __CXL_H
>> +
>> +#include <linux/ioport.h>
>> +
>> +enum cxl_resource {
>> + CXL_RES_DPA,
>> + CXL_RES_RAM,
>> + CXL_RES_PMEM,
>> +};
>> +
>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>> +
>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> + enum cxl_resource);
>> +#endif
>> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
>> new file mode 100644
>> index 000000000000..ad63560caa2c
>> --- /dev/null
>> +++ b/include/cxl/pci.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>> +
>> +#ifndef __CXL_ACCEL_PCI_H
>> +#define __CXL_ACCEL_PCI_H
>> +
>> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>> +#define CXL_DVSEC_PCIE_DEVICE 0
>> +#define CXL_DVSEC_CAP_OFFSET 0xA
>> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>> +#define CXL_DVSEC_CTRL_OFFSET 0xC
>> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
>> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
>> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
>> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
>> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
>> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>> +
>> +#endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 01/27] cxl: add type2 device basic support
2024-11-27 9:00 ` Alejandro Lucero Palau
@ 2024-11-27 9:07 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 9:07 UTC (permalink / raw)
To: Ben Cheatham, Lucero Palau, Alejandro
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/27/24 09:00, Alejandro Lucero Palau wrote:
>
> On 11/22/24 20:43, Ben Cheatham wrote:
>> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>>> From: Alejandro Lucero <alucerop@amd.com>
>>>
>>> Differentiate Type3, aka memory expanders, from Type2, aka device
>>> accelerators, with a new function for initializing cxl_dev_state.
>>>
>>> Create accessors to cxl_dev_state to be used by accel drivers.
>>>
>>> Based on previous work by Dan Williams [1]
>>>
>>> Link: [1]
>>> https://lore.kernel.org/linux-cxl/168592160379.1948938.12863272903570476312.stgit@dwillia2-xfh.jf.intel.com/
>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
>>> ---
>>> drivers/cxl/core/memdev.c | 51
>>> +++++++++++++++++++++++++++++++++++++++
>>> drivers/cxl/core/pci.c | 1 +
>>> drivers/cxl/cxlpci.h | 16 ------------
>>> drivers/cxl/pci.c | 13 +++++++---
>>> include/cxl/cxl.h | 21 ++++++++++++++++
>>> include/cxl/pci.h | 23 ++++++++++++++++++
>>> 6 files changed, 105 insertions(+), 20 deletions(-)
>>> create mode 100644 include/cxl/cxl.h
>>> create mode 100644 include/cxl/pci.h
>>>
>>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>>> index 84fefb76dafa..d083fd13a6dd 100644
>>> --- a/drivers/cxl/core/memdev.c
>>> +++ b/drivers/cxl/core/memdev.c
>>> @@ -1,6 +1,7 @@
>>> // SPDX-License-Identifier: GPL-2.0-only
>>> /* Copyright(c) 2020 Intel Corporation. */
>>> +#include <cxl/cxl.h>
>> Pedantic one, you'll want this at the end CXL does reverse christmas
>> tree
>> for #includes.
>
>
> That seems to be true for this file, but the reverse christmas tree is
> not applied through all the files in the cxl directory.
>
> I was told to put it in alphabetical order (not remember which
> specific file), what implies there is no agreement about how to put
> the header references.
>
> Anyway, I think for this one your suggestion makes sense.
>
>
>>> #include <linux/io-64-nonatomic-lo-hi.h>
>>> #include <linux/firmware.h>
>>> #include <linux/device.h>
>>> @@ -616,6 +617,25 @@ static void detach_memdev(struct work_struct
>>> *work)
>>> static struct lock_class_key cxl_memdev_key;
>>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev)
>>> +{
>>> + struct cxl_dev_state *cxlds;
>>> +
>>> + cxlds = kzalloc(sizeof(*cxlds), GFP_KERNEL);
>> Would it be better to use a devm_kzalloc() here? I'd imagine this
>> function
>> will be called as part of probe a majority of the time so I think the
>> automatic
>> cleanup would be nice here. If you did that, then I'd also rename the
>> function to
>> include devm_ as well.
>
>
> This is complicated. As I have said in other previous reviews
> regarding use of devm_* by the sfc changes in this patchset, it is
> not advice to use them inside the netdev subsystem. This is not the
> case here since it is cxl code, but in this case used by a netdev
> client (although other clients from other subsystems will likely come
> soon).
>
>
> So, I'm not sure about this one. I could add the specific function to
> use when released like when cxl_memdev_alloc is used by
> devm_cxl_add_memdev, but frankly, mixing devm with no devm allocations
> is a mess, at least in my view.
>
I forgot to mention another reason for not using devm and it is the fact
that the memory is not released until the driver is detached. If the cxl
initialization can fail and not being fatal, that means the memory not
released while the driver is being used. A specific CXL accelerator
driver, meaning the design relying on CXL, is not a problem, but a
driver using CXL as an option for better performance could keep the
memory unreleased as it is the case for sfc.
>
>>> + if (!cxlds)
>>> + return ERR_PTR(-ENOMEM);
>>> +
>>> + cxlds->dev = dev;
>>> + cxlds->type = CXL_DEVTYPE_DEVMEM;
>>> +
>>> + cxlds->dpa_res = DEFINE_RES_MEM_NAMED(0, 0, "dpa");
>>> + cxlds->ram_res = DEFINE_RES_MEM_NAMED(0, 0, "ram");
>>> + cxlds->pmem_res = DEFINE_RES_MEM_NAMED(0, 0, "pmem");
>>> +
>>> + return cxlds;
>>> +}
>>> +EXPORT_SYMBOL_NS_GPL(cxl_accel_state_create, CXL);
>>> +
>>> static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state
>>> *cxlds,
>>> const struct file_operations *fops)
>>> {
>>> @@ -693,6 +713,37 @@ static int cxl_memdev_open(struct inode *inode,
>>> struct file *file)
>>> return 0;
>>> }
>>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec)
>>> +{
>>> + cxlds->cxl_dvsec = dvsec;
>>> +}
>>> +EXPORT_SYMBOL_NS_GPL(cxl_set_dvsec, CXL);
>>> +
>>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial)
>>> +{
>>> + cxlds->serial = serial;
>>> +}
>>> +EXPORT_SYMBOL_NS_GPL(cxl_set_serial, CXL);
>>> +
>>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>>> + enum cxl_resource type)
>>> +{
>>> + switch (type) {
>>> + case CXL_RES_DPA:
>>> + cxlds->dpa_res = res;
>>> + return 0;
>>> + case CXL_RES_RAM:
>>> + cxlds->ram_res = res;
>>> + return 0;
>>> + case CXL_RES_PMEM:
>>> + cxlds->pmem_res = res;
>>> + return 0;
>>> + }
>>> +
>>> + return -EINVAL;
>>> +}
>>> +EXPORT_SYMBOL_NS_GPL(cxl_set_resource, CXL);
>>> +
>>> static int cxl_memdev_release_file(struct inode *inode, struct
>>> file *file)
>>> {
>>> struct cxl_memdev *cxlmd =
>>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
>>> index 420e4be85a1f..ff266e91ea71 100644
>>> --- a/drivers/cxl/core/pci.c
>>> +++ b/drivers/cxl/core/pci.c
>>> @@ -1,5 +1,6 @@
>>> // SPDX-License-Identifier: GPL-2.0-only
>>> /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
>>> +#include <cxl/pci.h>
>>> #include <linux/units.h>
>>> #include <linux/io-64-nonatomic-lo-hi.h>
>>> #include <linux/device.h>
>>> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
>>> index 4da07727ab9c..eb59019fe5f3 100644
>>> --- a/drivers/cxl/cxlpci.h
>>> +++ b/drivers/cxl/cxlpci.h
>>> @@ -14,22 +14,6 @@
>>> */
>>> #define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
>>> -/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>>> -#define CXL_DVSEC_PCIE_DEVICE 0
>>> -#define CXL_DVSEC_CAP_OFFSET 0xA
>>> -#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>>> -#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>>> -#define CXL_DVSEC_CTRL_OFFSET 0xC
>>> -#define CXL_DVSEC_MEM_ENABLE BIT(2)
>>> -#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
>>> -#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
>>> -#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>>> -#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>>> -#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>>> -#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
>>> -#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
>>> -#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>>> -
>>> #define CXL_DVSEC_RANGE_MAX 2
>>> /* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
>>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>>> index 188412d45e0d..0b910ef52db7 100644
>>> --- a/drivers/cxl/pci.c
>>> +++ b/drivers/cxl/pci.c
>>> @@ -1,5 +1,7 @@
>>> // SPDX-License-Identifier: GPL-2.0-only
>>> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>>> +#include <cxl/cxl.h>
>>> +#include <cxl/pci.h>
>>> #include <linux/unaligned.h>
>>> #include <linux/io-64-nonatomic-lo-hi.h>
>>> #include <linux/moduleparam.h>
>>> @@ -816,6 +818,7 @@ static int cxl_pci_probe(struct pci_dev *pdev,
>>> const struct pci_device_id *id)
>>> struct cxl_memdev *cxlmd;
>>> int i, rc, pmu_count;
>>> bool irq_avail;
>>> + u16 dvsec;
>>> /*
>>> * Double check the anonymous union trickery in struct cxl_regs
>>> @@ -836,13 +839,15 @@ static int cxl_pci_probe(struct pci_dev *pdev,
>>> const struct pci_device_id *id)
>>> pci_set_drvdata(pdev, cxlds);
>>> cxlds->rcd = is_cxl_restricted(pdev);
>>> - cxlds->serial = pci_get_dsn(pdev);
>>> - cxlds->cxl_dvsec = pci_find_dvsec_capability(
>>> - pdev, PCI_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
>>> - if (!cxlds->cxl_dvsec)
>>> + cxl_set_serial(cxlds, pci_get_dsn(pdev));
>>> + dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
>>> + CXL_DVSEC_PCIE_DEVICE);
>>> + if (!dvsec)
>>> dev_warn(&pdev->dev,
>>> "Device DVSEC not present, skip CXL.mem init\n");
>>> + cxl_set_dvsec(cxlds, dvsec);
>>> +
>>> rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
>>> if (rc)
>>> return rc;
>>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>>> new file mode 100644
>>> index 000000000000..19e5d883557a
>>> --- /dev/null
>>> +++ b/include/cxl/cxl.h
>> Is cxl.h the right name for this file? I initially thought this was
>> the cxl.h
>> under drivers/cxl. It looks like it's just type 2 related functions,
>> so maybe
>> "type2.h", or "accel.h" would be better? If the plan is to expose
>> more CXL
>> functionality not necessarily related to type 2 devices later I'm
>> fine with it,
>> and if no one else cares then I'm fine with it.
>
>
> I agree, but I did use cxl_accel_* in version 2 and it was suggested
> then to remove the accel part, so leaving it as it is now if none else
> cares about it.
>
> Thanks!
>
>
>>> @@ -0,0 +1,21 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/* Copyright(c) 2024 Advanced Micro Devices, Inc. */
>>> +
>>> +#ifndef __CXL_H
>>> +#define __CXL_H
>>> +
>>> +#include <linux/ioport.h>
>>> +
>>> +enum cxl_resource {
>>> + CXL_RES_DPA,
>>> + CXL_RES_RAM,
>>> + CXL_RES_PMEM,
>>> +};
>>> +
>>> +struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>>> +
>>> +void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>>> +void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
>>> +int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>>> + enum cxl_resource);
>>> +#endif
>>> diff --git a/include/cxl/pci.h b/include/cxl/pci.h
>>> new file mode 100644
>>> index 000000000000..ad63560caa2c
>>> --- /dev/null
>>> +++ b/include/cxl/pci.h
>>> @@ -0,0 +1,23 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
>>> +
>>> +#ifndef __CXL_ACCEL_PCI_H
>>> +#define __CXL_ACCEL_PCI_H
>>> +
>>> +/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
>>> +#define CXL_DVSEC_PCIE_DEVICE 0
>>> +#define CXL_DVSEC_CAP_OFFSET 0xA
>>> +#define CXL_DVSEC_MEM_CAPABLE BIT(2)
>>> +#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
>>> +#define CXL_DVSEC_CTRL_OFFSET 0xC
>>> +#define CXL_DVSEC_MEM_ENABLE BIT(2)
>>> +#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + ((i) * 0x10))
>>> +#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + ((i) * 0x10))
>>> +#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
>>> +#define CXL_DVSEC_MEM_ACTIVE BIT(1)
>>> +#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
>>> +#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + ((i) * 0x10))
>>> +#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + ((i) * 0x10))
>>> +#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
>>> +
>>> +#endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 02/27] sfc: add cxl support using new CXL API
2024-11-22 20:43 ` Ben Cheatham
@ 2024-11-27 9:15 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 9:15 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/22/24 20:43, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Add CXL initialization based on new CXL API for accel drivers and make
>> it dependable on kernel CXL configuration.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/net/ethernet/sfc/Kconfig | 7 +++
>> drivers/net/ethernet/sfc/Makefile | 1 +
>> drivers/net/ethernet/sfc/efx.c | 24 +++++++-
>> drivers/net/ethernet/sfc/efx_cxl.c | 88 +++++++++++++++++++++++++++
>> drivers/net/ethernet/sfc/efx_cxl.h | 28 +++++++++
>> drivers/net/ethernet/sfc/net_driver.h | 10 +++
>> 6 files changed, 157 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
>> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
>>
>> diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
>> index 3eb55dcfa8a6..a8bc777baa95 100644
>> --- a/drivers/net/ethernet/sfc/Kconfig
>> +++ b/drivers/net/ethernet/sfc/Kconfig
>> @@ -65,6 +65,13 @@ config SFC_MCDI_LOGGING
>> Driver-Interface) commands and responses, allowing debugging of
>> driver/firmware interaction. The tracing is actually enabled by
>> a sysfs file 'mcdi_logging' under the PCI device.
>> +config SFC_CXL
>> + bool "Solarflare SFC9100-family CXL support"
>> + depends on SFC && CXL_BUS && !(SFC=y && CXL_BUS=m)
> If I'm reading this right, you want to make sure that CXL_BUS is not set to 'm' when SFC is built-in. If that's
> the case, you can simplify this to "depends on SFC && CXL_BUS && CXL_BUS >= SFC" (or SFC <= CXL_BUS).
> I'm pretty sure you could also drop the middle part as well, so it would become "depends on SFC && CXL_BUS >= SFC".
> Also, this patch relies on the cxl_mem/cxl_acpi modules, right? If so, I would change the CXL_BUS above to one of
> those since they already depend on CXL_BUS IIRC.
This has been discussed internally and the decision was to follow what
the SFC_MTD option does. It is good enough for our purposes.
Thanks.
>> + default y
>> + help
>> + This enables CXL support by the driver relying on kernel support
>> + and hardware support.
> I think it would be good here to say what kernel support is being relied on. I'm 99% sure
> it's just the CXL driver, so saying it relies on the CXL driver/module(s) would be fine. I
> have no clue what hardware is needed for this support, so I can't make a recommendation
> there.
>
>>
>> source "drivers/net/ethernet/sfc/falcon/Kconfig"
>> source "drivers/net/ethernet/sfc/siena/Kconfig"
>> diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
>> index 8f446b9bd5ee..e909cafd5908 100644
>> --- a/drivers/net/ethernet/sfc/Makefile
>> +++ b/drivers/net/ethernet/sfc/Makefile
>> @@ -13,6 +13,7 @@ sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
>> mae.o tc.o tc_bindings.o tc_counters.o \
>> tc_encap_actions.o tc_conntrack.o
>>
>> +sfc-$(CONFIG_SFC_CXL) += efx_cxl.o
>> obj-$(CONFIG_SFC) += sfc.o
>>
>> obj-$(CONFIG_SFC_FALCON) += falcon/
>> diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
>> index 36b3b57e2055..5f7c910a14a5 100644
>> --- a/drivers/net/ethernet/sfc/efx.c
>> +++ b/drivers/net/ethernet/sfc/efx.c
>> @@ -33,6 +33,9 @@
>> #include "selftest.h"
>> #include "sriov.h"
>> #include "efx_devlink.h"
>> +#ifdef CONFIG_SFC_CXL
>> +#include "efx_cxl.h"
>> +#endif
>>
>> #include "mcdi_port_common.h"
>> #include "mcdi_pcol.h"
>> @@ -903,12 +906,17 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
>> efx_pci_remove_main(efx);
>>
>> efx_fini_io(efx);
>> +
>> + probe_data = container_of(efx, struct efx_probe_data, efx);
>> +#ifdef CONFIG_SFC_CXL
>> + efx_cxl_exit(probe_data);
>> +#endif
>> +
>> pci_dbg(efx->pci_dev, "shutdown successful\n");
>>
>> efx_fini_devlink_and_unlock(efx);
>> efx_fini_struct(efx);
>> free_netdev(efx->net_dev);
>> - probe_data = container_of(efx, struct efx_probe_data, efx);
>> kfree(probe_data);
>> };
>>
>> @@ -1113,6 +1121,17 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
>> if (rc)
>> goto fail2;
>>
>> +#ifdef CONFIG_SFC_CXL
>> + /* A successful cxl initialization implies a CXL region created to be
>> + * used for PIO buffers. If there is no CXL support, or initialization
>> + * fails, efx_cxl_pio_initialised wll be false and legacy PIO buffers
>> + * defined at specific PCI BAR regions will be used.
>> + */
>> + rc = efx_cxl_init(probe_data);
>> + if (rc)
>> + pci_err(pci_dev, "CXL initialization failed with error %d\n", rc);
>> +
>> +#endif
>> rc = efx_pci_probe_post_io(efx);
>> if (rc) {
>> /* On failure, retry once immediately.
>> @@ -1384,3 +1403,6 @@ MODULE_AUTHOR("Solarflare Communications and "
>> MODULE_DESCRIPTION("Solarflare network driver");
>> MODULE_LICENSE("GPL");
>> MODULE_DEVICE_TABLE(pci, efx_pci_table);
>> +#ifdef CONFIG_SFC_CXL
>> +MODULE_SOFTDEP("pre: cxl_core cxl_port cxl_acpi cxl-mem");
>> +#endif
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
>> new file mode 100644
>> index 000000000000..99f396028639
>> --- /dev/null
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
>> @@ -0,0 +1,88 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/****************************************************************************
>> + *
>> + * Driver for AMD network controllers and boards
>> + * Copyright (C) 2024, Advanced Micro Devices, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published
>> + * by the Free Software Foundation, incorporated herein by reference.
>> + */
>> +
>> +#include <cxl/cxl.h>
>> +#include <cxl/pci.h>
>> +#include <linux/pci.h>
>> +
>> +#include "net_driver.h"
>> +#include "efx_cxl.h"
>> +
>> +#define EFX_CTPIO_BUFFER_SIZE SZ_256M
>> +
>> +int efx_cxl_init(struct efx_probe_data *probe_data)
>> +{
>> + struct efx_nic *efx = &probe_data->efx;
>> + struct pci_dev *pci_dev;
>> + struct efx_cxl *cxl;
>> + struct resource res;
>> + u16 dvsec;
>> + int rc;
>> +
>> + pci_dev = efx->pci_dev;
>> + probe_data->cxl_pio_initialised = false;
>> +
>> + dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
>> + CXL_DVSEC_PCIE_DEVICE);
>> + if (!dvsec)
>> + return 0;
>> +
>> + pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
>> +
>> + cxl = kzalloc(sizeof(*cxl), GFP_KERNEL);
>> + if (!cxl)
>> + return -ENOMEM;
>> +
>> + cxl->cxlds = cxl_accel_state_create(&pci_dev->dev);
>> + if (IS_ERR(cxl->cxlds)) {
>> + pci_err(pci_dev, "CXL accel device state failed");
>> + rc = -ENOMEM;
>> + goto err1;
>> + }
>> +
>> + cxl_set_dvsec(cxl->cxlds, dvsec);
>> + cxl_set_serial(cxl->cxlds, pci_dev->dev.id);
>> +
>> + res = DEFINE_RES_MEM(0, EFX_CTPIO_BUFFER_SIZE);
>> + if (cxl_set_resource(cxl->cxlds, res, CXL_RES_DPA)) {
>> + pci_err(pci_dev, "cxl_set_resource DPA failed\n");
>> + rc = -EINVAL;
>> + goto err2;
>> + }
>> +
>> + res = DEFINE_RES_MEM_NAMED(0, EFX_CTPIO_BUFFER_SIZE, "ram");
>> + if (cxl_set_resource(cxl->cxlds, res, CXL_RES_RAM)) {
>> + pci_err(pci_dev, "cxl_set_resource RAM failed\n");
>> + rc = -EINVAL;
>> + goto err2;
>> + }
>> +
>> + probe_data->cxl = cxl;
>> +
>> + return 0;
>> +
>> +err2:
>> + kfree(cxl->cxlds);
>> +err1:
>> + kfree(cxl);
>> + return rc;
>> +
>> +}
>> +
>> +void efx_cxl_exit(struct efx_probe_data *probe_data)
>> +{
>> + if (probe_data->cxl) {
>> + kfree(probe_data->cxl->cxlds);
>> + kfree(probe_data->cxl);
>> + }
>> +}
>> +
>> +MODULE_IMPORT_NS(CXL);
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
>> new file mode 100644
>> index 000000000000..90fa46bc94db
>> --- /dev/null
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.h
>> @@ -0,0 +1,28 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/****************************************************************************
>> + * Driver for AMD network controllers and boards
>> + * Copyright (C) 2024, Advanced Micro Devices, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published
>> + * by the Free Software Foundation, incorporated herein by reference.
>> + */
>> +
>> +#ifndef EFX_CXL_H
>> +#define EFX_CXL_H
>> +
>> +struct efx_nic;
>> +
>> +struct efx_cxl {
>> + struct cxl_dev_state *cxlds;
>> + struct cxl_memdev *cxlmd;
>> + struct cxl_root_decoder *cxlrd;
>> + struct cxl_port *endpoint;
>> + struct cxl_endpoint_decoder *cxled;
>> + struct cxl_region *efx_region;
>> + void __iomem *ctpio_cxl;
>> +};
>> +
>> +int efx_cxl_init(struct efx_probe_data *probe_data);
>> +void efx_cxl_exit(struct efx_probe_data *probe_data);
>> +#endif
> I know nothing about the /net code so sorry if this is just a style thing, but
> you can delete the #ifdef CONFIG_SFC_CXL in efx.c (and elsewhere) if you add stubs
> for when CONFIG_SFC_CXL=n. So the above would look like:
>
> #if IS_ENABLED(CONFIG_SFC_CXL) // or #ifdef CONFIG_SFC_CXL
> int efx_cxl_init(struct efx_probe_data *probe_data);
> void efx_cxl_exit(struct efx_probe_data *probe_data);
> #else
> static inline int efx_cxl_init(struct efx_probe_data *probe_data) { return 0; }
> static inline void efx_cxl_exit(struct efx_probe_data *probe_data) {}
> #endif
>
> and then you can just #include efx_cxl.h unconditionally.
>
>> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
>> index b85c51cbe7f9..efc6d90380b9 100644
>> --- a/drivers/net/ethernet/sfc/net_driver.h
>> +++ b/drivers/net/ethernet/sfc/net_driver.h
>> @@ -1160,14 +1160,24 @@ struct efx_nic {
>> atomic_t n_rx_noskb_drops;
>> };
>>
>> +#ifdef CONFIG_SFC_CXL
>> +struct efx_cxl;
>> +#endif
>> +
>> /**
>> * struct efx_probe_data - State after hardware probe
>> * @pci_dev: The PCI device
>> * @efx: Efx NIC details
>> + * @cxl: details of related cxl objects
>> + * @cxl_pio_initialised: cxl initialization outcome.
>> */
>> struct efx_probe_data {
>> struct pci_dev *pci_dev;
>> struct efx_nic efx;
>> +#ifdef CONFIG_SFC_CXL
>> + struct efx_cxl *cxl;
>> + bool cxl_pio_initialised;
>> +#endif
>> };
>>
>> static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 02/27] sfc: add cxl support using new CXL API
2024-11-26 18:08 ` Fan Ni
@ 2024-11-27 9:17 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 9:17 UTC (permalink / raw)
To: Fan Ni, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/26/24 18:08, Fan Ni wrote:
> On Mon, Nov 18, 2024 at 04:44:09PM +0000, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Add CXL initialization based on new CXL API for accel drivers and make
>> it dependable on kernel CXL configuration.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/net/ethernet/sfc/Kconfig | 7 +++
>> drivers/net/ethernet/sfc/Makefile | 1 +
>> drivers/net/ethernet/sfc/efx.c | 24 +++++++-
>> drivers/net/ethernet/sfc/efx_cxl.c | 88 +++++++++++++++++++++++++++
>> drivers/net/ethernet/sfc/efx_cxl.h | 28 +++++++++
>> drivers/net/ethernet/sfc/net_driver.h | 10 +++
>> 6 files changed, 157 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
>> create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
> ...
>> + res = DEFINE_RES_MEM_NAMED(0, EFX_CTPIO_BUFFER_SIZE, "ram");
>> + if (cxl_set_resource(cxl->cxlds, res, CXL_RES_RAM)) {
>> + pci_err(pci_dev, "cxl_set_resource RAM failed\n");
>> + rc = -EINVAL;
>> + goto err2;
>> + }
>> +
>> + probe_data->cxl = cxl;
>> +
>> + return 0;
>> +
>> +err2:
>> + kfree(cxl->cxlds);
>> +err1:
>> + kfree(cxl);
>> + return rc;
>> +
> Unwanted blank line here.
I'll fix it.
Thanks!
> Fan
>> +}
>> +
>> +void efx_cxl_exit(struct efx_probe_data *probe_data)
>> +{
>> + if (probe_data->cxl) {
>> + kfree(probe_data->cxl->cxlds);
>> + kfree(probe_data->cxl);
>> + }
>> +}
>> +
>> +MODULE_IMPORT_NS(CXL);
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
>> new file mode 100644
>> index 000000000000..90fa46bc94db
>> --- /dev/null
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.h
>> @@ -0,0 +1,28 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/****************************************************************************
>> + * Driver for AMD network controllers and boards
>> + * Copyright (C) 2024, Advanced Micro Devices, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published
>> + * by the Free Software Foundation, incorporated herein by reference.
>> + */
>> +
>> +#ifndef EFX_CXL_H
>> +#define EFX_CXL_H
>> +
>> +struct efx_nic;
>> +
>> +struct efx_cxl {
>> + struct cxl_dev_state *cxlds;
>> + struct cxl_memdev *cxlmd;
>> + struct cxl_root_decoder *cxlrd;
>> + struct cxl_port *endpoint;
>> + struct cxl_endpoint_decoder *cxled;
>> + struct cxl_region *efx_region;
>> + void __iomem *ctpio_cxl;
>> +};
>> +
>> +int efx_cxl_init(struct efx_probe_data *probe_data);
>> +void efx_cxl_exit(struct efx_probe_data *probe_data);
>> +#endif
>> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
>> index b85c51cbe7f9..efc6d90380b9 100644
>> --- a/drivers/net/ethernet/sfc/net_driver.h
>> +++ b/drivers/net/ethernet/sfc/net_driver.h
>> @@ -1160,14 +1160,24 @@ struct efx_nic {
>> atomic_t n_rx_noskb_drops;
>> };
>>
>> +#ifdef CONFIG_SFC_CXL
>> +struct efx_cxl;
>> +#endif
>> +
>> /**
>> * struct efx_probe_data - State after hardware probe
>> * @pci_dev: The PCI device
>> * @efx: Efx NIC details
>> + * @cxl: details of related cxl objects
>> + * @cxl_pio_initialised: cxl initialization outcome.
>> */
>> struct efx_probe_data {
>> struct pci_dev *pci_dev;
>> struct efx_nic efx;
>> +#ifdef CONFIG_SFC_CXL
>> + struct efx_cxl *cxl;
>> + bool cxl_pio_initialised;
>> +#endif
>> };
>>
>> static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
>> --
>> 2.17.1
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 04/27] cxl/pci: add check for validating capabilities
2024-11-22 20:44 ` Ben Cheatham
@ 2024-11-27 11:34 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 11:34 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/22/24 20:44, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> During CXL device initialization supported capabilities by the device
>> are discovered. Type3 and Type2 devices have different mandatory
>> capabilities and a Type2 expects a specific set including optional
>> capabilities.
>>
>> Add a function for checking expected capabilities against those found
>> during initialization. Allow those mandatory/expected capabilities to
>> be a subset of the capabilities found.
>>
>> Rely on this function for validating capabilities instead of when CXL
>> regs are probed.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/pci.c | 22 ++++++++++++++++++++++
>> drivers/cxl/core/regs.c | 9 ---------
>> drivers/cxl/pci.c | 24 ++++++++++++++++++++++++
>> include/cxl/cxl.h | 6 +++++-
>> 4 files changed, 51 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
>> index ff266e91ea71..a1942b7be0bc 100644
>> --- a/drivers/cxl/core/pci.c
>> +++ b/drivers/cxl/core/pci.c
>> @@ -8,6 +8,7 @@
>> #include <linux/pci.h>
>> #include <linux/pci-doe.h>
>> #include <linux/aer.h>
>> +#include <cxl/cxl.h>
>> #include <cxlpci.h>
>> #include <cxlmem.h>
>> #include <cxl.h>
>> @@ -1055,3 +1056,24 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
>>
>> return 0;
>> }
>> +
>> +bool cxl_pci_check_caps(struct cxl_dev_state *cxlds, unsigned long *expected_caps,
>> + unsigned long *current_caps, bool is_subset)
>> +{
>> + DECLARE_BITMAP(subset, CXL_MAX_CAPS);
>> +
>> + if (current_caps)
>> + bitmap_copy(current_caps, cxlds->capabilities, CXL_MAX_CAPS);
>> +
>> + dev_dbg(cxlds->dev, "Checking cxlds caps 0x%08lx vs expected caps 0x%08lx\n",
>> + *cxlds->capabilities, *expected_caps);
>> +
>> + /* Checking a minimum of mandatory capabilities? */
>> + if (is_subset) {
>> + bitmap_and(subset, cxlds->capabilities, expected_caps, CXL_MAX_CAPS);
>> + return bitmap_equal(subset, expected_caps, CXL_MAX_CAPS);
>
> It looks like there's a function called bitmap_subset(), does that not do the above? I didn't
> look at the function since it's the end of the day when I'm writing this and my brain is tired,
> but I'd rather that be used if possible. I also don't think you need this is_subset parameter and
> else branch. I don't see anyone using this function where some expected capabilities are optional
> and others mandatory. If that's the case then they'd probably split the calls instead.
That is a funny one. I did not realize such bitmap_subset did exist!
I've just tried it and it works as expected. It is going to make the
code simpler!
Thanks!
>> + } else {
>> + return bitmap_equal(cxlds->capabilities, expected_caps, CXL_MAX_CAPS);
>> + }
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_pci_check_caps, CXL);
>> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
>> index 8287ec45b018..3b3965706414 100644
>> --- a/drivers/cxl/core/regs.c
>> +++ b/drivers/cxl/core/regs.c
>> @@ -444,15 +444,6 @@ static int cxl_probe_regs(struct cxl_register_map *map, unsigned long *caps)
>> case CXL_REGLOC_RBI_MEMDEV:
>> dev_map = &map->device_map;
>> cxl_probe_device_regs(host, base, dev_map, caps);
>> - if (!dev_map->status.valid || !dev_map->mbox.valid ||
>> - !dev_map->memdev.valid) {
>> - dev_err(host, "registers not found: %s%s%s\n",
>> - !dev_map->status.valid ? "status " : "",
>> - !dev_map->mbox.valid ? "mbox " : "",
>> - !dev_map->memdev.valid ? "memdev " : "");
>> - return -ENXIO;
>> - }
>> -
>> dev_dbg(host, "Probing device registers...\n");
>> break;
>> default:
>> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
>> index 528d4ca79fd1..5de1473a79da 100644
>> --- a/drivers/cxl/pci.c
>> +++ b/drivers/cxl/pci.c
>> @@ -813,6 +813,8 @@ static int cxl_pci_type3_init_mailbox(struct cxl_dev_state *cxlds)
>> static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> {
>> struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
>> + DECLARE_BITMAP(expected, CXL_MAX_CAPS);
>> + DECLARE_BITMAP(found, CXL_MAX_CAPS);
>> struct cxl_memdev_state *mds;
>> struct cxl_dev_state *cxlds;
>> struct cxl_register_map map;
>> @@ -874,6 +876,28 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> if (rc)
>> dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
>>
>> + bitmap_clear(expected, 0, CXL_MAX_CAPS);
>> +
>> + /*
>> + * These are the mandatory capabilities for a Type3 device.
>> + * Only checking capabilities used by current Linux drivers.
>> + */
>> + bitmap_set(expected, CXL_DEV_CAP_HDM, 1);
>> + bitmap_set(expected, CXL_DEV_CAP_DEV_STATUS, 1);
>> + bitmap_set(expected, CXL_DEV_CAP_MAILBOX_PRIMARY, 1);
>> + bitmap_set(expected, CXL_DEV_CAP_DEV_STATUS, 1);
>> +
>> + /*
>> + * Checking mandatory caps are there as, at least, a subset of those
>> + * found.
>> + */
>> + if (!cxl_pci_check_caps(cxlds, expected, found, true)) {
>> + dev_err(&pdev->dev,
>> + "Expected mandatory capabilities not found: (%08lx - %08lx)\n",
>> + *expected, *found);
>> + return -ENXIO;
>> + }
>> +
>> rc = cxl_pci_type3_init_mailbox(cxlds);
>> if (rc)
>> return rc;
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index dcc9ec8a0aec..ab243ab8024f 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -39,7 +39,7 @@ enum cxl_dev_cap {
>> CXL_DEV_CAP_DEV_STATUS,
>> CXL_DEV_CAP_MAILBOX_PRIMARY,
>> CXL_DEV_CAP_MEMDEV,
>> - CXL_MAX_CAPS = 32
>> + CXL_MAX_CAPS = 64
>> };
>>
>> struct cxl_dev_state *cxl_accel_state_create(struct device *dev);
>> @@ -48,4 +48,8 @@ void cxl_set_dvsec(struct cxl_dev_state *cxlds, u16 dvsec);
>> void cxl_set_serial(struct cxl_dev_state *cxlds, u64 serial);
>> int cxl_set_resource(struct cxl_dev_state *cxlds, struct resource res,
>> enum cxl_resource);
>> +bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
>> + unsigned long *expected_caps,
>> + unsigned long *current_caps,
>> + bool is_subset);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 06/27] cxl: add function for type2 cxl regs setup
2024-11-21 22:34 ` Alison Schofield
@ 2024-11-27 11:46 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 11:46 UTC (permalink / raw)
To: Alison Schofield, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/21/24 22:34, Alison Schofield wrote:
> On Mon, Nov 18, 2024 at 04:44:13PM +0000, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Create a new function for a type2 device initialising
>> cxl_dev_state struct regarding cxl regs setup and mapping.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/pci.c | 47 ++++++++++++++++++++++++++++++++++++++++++
>> include/cxl/cxl.h | 2 ++
>> 2 files changed, 49 insertions(+)
>>
>> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> snip
>
>> +
>> +int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds)
>> +{
>> + int rc;
> maybe init to 0
It is not used before the next call initialising it, so it is not needed.
>> +
>> + rc = cxl_pci_setup_memdev_regs(pdev, cxlds);
>> + if (rc)
>> + return rc;
>> +
>> + rc = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
>> + &cxlds->reg_map, cxlds->capabilities);
>> + if (rc) {
>> + dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
>> + return rc;
>> + }
>> +
>> + if (!test_bit(CXL_CM_CAP_CAP_ID_RAS, cxlds->capabilities))
>> + return rc;
> init rc to 0 or return 0 directly here
>
>> +
>> + rc = cxl_map_component_regs(&cxlds->reg_map,
>> + &cxlds->regs.component,
>> + BIT(CXL_CM_CAP_CAP_ID_RAS));
>> + if (rc)
>> + dev_dbg(&pdev->dev, "Failed to map RAS capability.\n");
>> +
>> + return rc;
> init rc to 0 or return 0 directly here
>
>
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_pci_accel_setup_regs, CXL);
> snip
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources
2024-11-21 21:00 ` Alison Schofield
@ 2024-11-27 14:56 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 14:56 UTC (permalink / raw)
To: Alison Schofield
Cc: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
martin.habets, edward.cree, davem, kuba, pabeni, edumazet
On 11/21/24 21:00, Alison Schofield wrote:
> On Thu, Nov 21, 2024 at 09:22:33AM +0000, Alejandro Lucero Palau wrote:
>> On 11/21/24 02:46, Alison Schofield wrote:
>>> On Mon, Nov 18, 2024 at 04:44:17PM +0000, alejandro.lucero-palau@amd.com wrote:
>>>> From: Alejandro Lucero <alucerop@amd.com>
>>>>
>>>> For a resource defined with size zero, resource_contains returns
>>>> always true.
>>>>
>>> I'm not following the premise above -
>>>
>>> Looking at resource_contains() and the changes made below,
>>> it seems the concern is with &cxlds->ram_res or &cxlds->pmem_res
>>> being zero - because we already checked that the second param
>>> 'res' is not zero a few lines above.
>>>
>>> Looking at what happens when r1 is of size 0, I don't see how
>>> resource_contains() returns always true.
>>>
>>> In resource_contains(r1, r2), if r1 is of size 0, r1->start == r1->end.
>>> The func can only return true if r2 is also of size 0 and located at
>>> exactly r1->start. But, in this case, we are not going to get there
>>> because we never send an r2 of size 0.
>>>
>>> For any non-zero size r2 the func will always return false because
>>> the size 0 r1 cannot encompass any range.
>>>
>>> I could be misreading it all ;)
>>
>> The key is to know how a resource with size 0 is initialized, what can be
>> understood looking at DEFINE_RES_NAMED macro. The end field is set as size
>> - 1.
>>
>> With unsigned variables, as it is the case here, it means to have a resource
>> as big as possible ... if you do not check first the size is not 0.
>>
>> The pmem resource is explicitly initialized inside cxl_accel_state_create in
>> the previous patch, so it has:
>>
>> pmem_res->start = 0, pmem_res.end = 0xffffffffffffffff
>>
>> the resource checked against is defined with, for example, a 256MB size:
>>
>> res.start =0, res.end = 0xfffffff
>>
>>
>> if you then use resource_contains(pmem_res, res), that implies always true,
>> whatever the res range defined.
>>
>>
>> All this confused me as well when facing it initially. I hope this
>> explanation makes sense.
>>
> Thanks for the explanation! I'm wondering if we are leaving a trap for the next
> developer.
>
> resource_contains() seems to have intended that a check for IORESOURCE_UNSET
> would take care of the zero size case:
>
> (5edb93b89f6c resource: Add resource_contains)
>
> and it would if folks used _UNSET. Some check r1->start before calling
> resource_contains().
>
> One option would be to use _UNSET in this case, but that only covers us here,
> and doesn't remove the trap ;)
>
> How about hardening resource_contains():
>
> ie: make resource_contains() return false if either res empty
>
> /* True iff r1 completely contains r2 */
> static inline bool resource_contains(const struct resource *r1, const struct resource *r2)
> {
> + if (!resource_size(r1) || !resource_size(r2))
> + return false;
> if (resource_type(r1) != resource_type(r2))
> return false;
> if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET)
> return false;
> return r1->start <= r2->start && r1->end >= r2->end;
> }
I can try that. If there is a good reason for not hardening it, we will
know.
Thanks!
> -- Alison
>
>>> --Alison
>>>
>>>
>>>> Add resource size check before using it.
>>>>
>>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>>> ---
>>>> drivers/cxl/core/hdm.c | 7 +++++--
>>>> 1 file changed, 5 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>>>> index 223c273c0cd1..c58d6b8f9b58 100644
>>>> --- a/drivers/cxl/core/hdm.c
>>>> +++ b/drivers/cxl/core/hdm.c
>>>> @@ -327,10 +327,13 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
>>>> cxled->dpa_res = res;
>>>> cxled->skip = skipped;
>>>> - if (resource_contains(&cxlds->pmem_res, res))
>>>> + if (resource_size(&cxlds->pmem_res) &&
>>>> + resource_contains(&cxlds->pmem_res, res)) {
>>>> cxled->mode = CXL_DECODER_PMEM;
>>>> - else if (resource_contains(&cxlds->ram_res, res))
>>>> + } else if (resource_size(&cxlds->ram_res) &&
>>>> + resource_contains(&cxlds->ram_res, res)) {
>>>> cxled->mode = CXL_DECODER_RAM;
>>>> + }
>>>> else {
>>>> dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
>>>> port->id, cxled->cxld.id, cxled->dpa_res);
>>>> --
>>>> 2.17.1
>>>>
>>>>
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 11/27] cxl: add function for setting media ready by a driver
2024-11-22 20:45 ` Ben Cheatham
@ 2024-11-27 15:07 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 15:07 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet, Cheatham, Benjamin
On 11/22/24 20:45, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> A Type-2 driver can require to set the memory availability explicitly.
> Little grammar nit, I think "may be required" reads better. I would also say
> why, for example: "... set the memory availability explicitly due to the
> possible lack of a mailbox".
>
It makes sense. I'll change it.
Thanks
>> Add a function to the exported CXL API for accelerator drivers.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
> Actual patch contents LGTM, so regardless of nit above:
> Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
>
>> drivers/cxl/core/memdev.c | 6 ++++++
>> include/cxl/cxl.h | 1 +
>> 2 files changed, 7 insertions(+)
>>
>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>> index 7450172c1864..d746c8a1021c 100644
>> --- a/drivers/cxl/core/memdev.c
>> +++ b/drivers/cxl/core/memdev.c
>> @@ -795,6 +795,12 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type)
>> }
>> EXPORT_SYMBOL_NS_GPL(cxl_release_resource, CXL);
>>
>> +void cxl_set_media_ready(struct cxl_dev_state *cxlds)
>> +{
>> + cxlds->media_ready = true;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_set_media_ready, CXL);
>> +
>> static int cxl_memdev_release_file(struct inode *inode, struct file *file)
>> {
>> struct cxl_memdev *cxlmd =
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index e0bafd066b93..6033ce84b3d3 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -56,4 +56,5 @@ bool cxl_pci_check_caps(struct cxl_dev_state *cxlds,
>> int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
>> int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
>> int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
>> +void cxl_set_media_ready(struct cxl_dev_state *cxlds);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 13/27] cxl: prepare memdev creation for type2
2024-11-22 20:45 ` Ben Cheatham
@ 2024-11-27 16:09 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 16:09 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, dan.j.williams, martin.habets, edward.cree, davem,
pabeni, edumazet, kuba, netdev, Cheatham, Benjamin
On 11/22/24 20:45, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device when
>> creating a memdev leading to problems when obtaining cxl_memdev_state
>> references from a CXL_DEVTYPE_DEVMEM type. This last device type is
>> managed by a specific vendor driver and does not need same sysfs files
>> since not userspace intervention is expected.
>>
>> Create a new cxl_mem device type with no attributes for Type2.
>>
>> Avoid debugfs files relying on existence of clx_memdev_state.
>>
>> Make devm_cxl_add_memdev accesible from a accel driver.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/cdat.c | 3 +++
>> drivers/cxl/core/memdev.c | 15 +++++++++++++--
>> drivers/cxl/core/region.c | 3 ++-
>> drivers/cxl/mem.c | 25 +++++++++++++++++++------
>> include/cxl/cxl.h | 2 ++
>> 5 files changed, 39 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
>> index e9cd7939c407..192cff18ea25 100644
>> --- a/drivers/cxl/core/cdat.c
>> +++ b/drivers/cxl/core/cdat.c
>> @@ -577,6 +577,9 @@ static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxle
>> struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
>> struct cxl_dpa_perf *perf;
>>
>> + if (!mds)
>> + return ERR_PTR(-EINVAL);
>> +
>> switch (mode) {
>> case CXL_DECODER_RAM:
>> perf = &mds->ram_perf;
>> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
>> index d746c8a1021c..df31eea0c06b 100644
>> --- a/drivers/cxl/core/memdev.c
>> +++ b/drivers/cxl/core/memdev.c
>> @@ -547,9 +547,17 @@ static const struct device_type cxl_memdev_type = {
>> .groups = cxl_memdev_attribute_groups,
>> };
>>
>> +static const struct device_type cxl_accel_memdev_type = {
>> + .name = "cxl_memdev",
> I would like to see a different name than cxl_memdev here, since this is technically
> a different type and I could see it being confusing sysfs-wise. Maybe "cxl_acceldev"
> or "cxl_accel_memdev" instead?
Yes, it makes sense.
>> + .release = cxl_memdev_release,
>> + .devnode = cxl_memdev_devnode,
>> +};
>> +
>> bool is_cxl_memdev(const struct device *dev)
>> {
>> - return dev->type == &cxl_memdev_type;
>> + return (dev->type == &cxl_memdev_type ||
>> + dev->type == &cxl_accel_memdev_type);
>> +
>> }
>> EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
>>
>> @@ -660,7 +668,10 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
>> dev->parent = cxlds->dev;
>> dev->bus = &cxl_bus_type;
>> dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
>> - dev->type = &cxl_memdev_type;
>> + if (cxlds->type == CXL_DEVTYPE_DEVMEM)
>> + dev->type = &cxl_accel_memdev_type;
>> + else
>> + dev->type = &cxl_memdev_type;
>> device_set_pm_not_required(dev);
>> INIT_WORK(&cxlmd->detach_work, detach_memdev);
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index dff618c708dc..622e3bb2e04b 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -1948,7 +1948,8 @@ static int cxl_region_attach(struct cxl_region *cxlr,
>> return -EINVAL;
>> }
>>
>> - cxl_region_perf_data_calculate(cxlr, cxled);
>> + if (cxlr->type == CXL_DECODER_HOSTONLYMEM)
>> + cxl_region_perf_data_calculate(cxlr, cxled);
>>
>> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
>> int i;
>> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
>> index a9fd5cd5a0d2..cb771bf196cd 100644
>> --- a/drivers/cxl/mem.c
>> +++ b/drivers/cxl/mem.c
>> @@ -130,12 +130,18 @@ static int cxl_mem_probe(struct device *dev)
>> dentry = cxl_debugfs_create_dir(dev_name(dev));
>> debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
>>
>> - if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
>> - debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
>> - &cxl_poison_inject_fops);
>> - if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
>> - debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
>> - &cxl_poison_clear_fops);
>> + /*
>> + * Avoid poison debugfs files for Type2 devices as they rely on
>> + * cxl_memdev_state.
>> + */
>> + if (mds) {
>> + if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
>> + debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
>> + &cxl_poison_inject_fops);
>> + if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
>> + debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
>> + &cxl_poison_clear_fops);
>> + }
>>
>> rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
>> if (rc)
>> @@ -219,6 +225,13 @@ static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
>> struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
>> struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
>>
>> + /*
>> + * Avoid poison sysfs files for Type2 devices as they rely on
>> + * cxl_memdev_state.
>> + */
>> + if (!mds)
>> + return 0;
> cxl_accel_memdev don't use the same attributes, so I imagine this modification isn't needed?
> I'm probably just missing something here.
This function is invoked for a Type2, as the cxl_mem device is created
and the attr group attached by default.
So this is needed or the reference will be pointing to unknown data and
the kernel, if we are lucky, getting a null pointer or a wrong pointer
making things worse.
>> +
>> if (a == &dev_attr_trigger_poison_list.attr)
>> if (!test_bit(CXL_POISON_ENABLED_LIST,
>> mds->poison.enabled_cmds))
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 6033ce84b3d3..5608ed0f5f15 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -57,4 +57,6 @@ int cxl_pci_accel_setup_regs(struct pci_dev *pdev, struct cxl_dev_state *cxlds);
>> int cxl_request_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
>> int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
>> void cxl_set_media_ready(struct cxl_dev_state *cxlds);
>> +struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
>> + struct cxl_dev_state *cxlds);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration
2024-11-22 20:45 ` Ben Cheatham
@ 2024-11-27 16:32 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 16:32 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/22/24 20:45, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> CXL region creation involves allocating capacity from device DPA
>> (device-physical-address space) and assigning it to decode a given HPA
>> (host-physical-address space). Before determining how much DPA to
>> allocate the amount of available HPA must be determined. Also, not all
>> HPA is create equal, some specifically targets RAM, some target PMEM,
>> some is prepared for device-memory flows like HDM-D and HDM-DB, and some
>> is host-only (HDM-H).
>>
>> Wrap all of those concerns into an API that retrieves a root decoder
>> (platform CXL window) that fits the specified constraints and the
>> capacity available for a new region.
>>
>> Based on https://lore.kernel.org/linux-cxl/168592159290.1948938.13522227102445462976.stgit@dwillia2-xfh.jf.intel.com/
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
>> ---
>> drivers/cxl/core/region.c | 141 ++++++++++++++++++++++++++++++++++++++
>> drivers/cxl/cxl.h | 3 +
>> include/cxl/cxl.h | 8 +++
>> 3 files changed, 152 insertions(+)
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index 622e3bb2e04b..d107cc1b4350 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -687,6 +687,147 @@ static int free_hpa(struct cxl_region *cxlr)
>> return 0;
>> }
>>
>> +struct cxlrd_max_context {
>> + struct device *host_bridge;
>> + unsigned long flags;
>> + resource_size_t max_hpa;
>> + struct cxl_root_decoder *cxlrd;
>> +};
>> +
>> +static int find_max_hpa(struct device *dev, void *data)
>> +{
>> + struct cxlrd_max_context *ctx = data;
>> + struct cxl_switch_decoder *cxlsd;
>> + struct cxl_root_decoder *cxlrd;
>> + struct resource *res, *prev;
>> + struct cxl_decoder *cxld;
>> + resource_size_t max;
>> +
>> + if (!is_root_decoder(dev))
>> + return 0;
>> +
>> + cxlrd = to_cxl_root_decoder(dev);
>> + cxlsd = &cxlrd->cxlsd;
>> + cxld = &cxlsd->cxld;
>> + if ((cxld->flags & ctx->flags) != ctx->flags) {
>> + dev_dbg(dev, "%s, flags not matching: %08lx vs %08lx\n",
>> + __func__, cxld->flags, ctx->flags);
>> + return 0;
>> + }
>> +
>> + /* An accelerator can not be part of an interleaved HPA range. */
> Someone else can weigh in on this, but I would also specify that this is a kernel/driver restriction,
> not a spec one.
>
Right. This was suggested for simplifying the code with the
current/expected devices, and I bet we will not see such a case for a
good number of years, but I agree to add that comment.
>> + if (cxld->interleave_ways != 1) {
>> + dev_dbg(dev, "%s, interleave_ways not matching\n", __func__);
>> + return 0;
>> + }
>> +
>> + guard(rwsem_read)(&cxl_region_rwsem);
>> + if (ctx->host_bridge != cxlsd->target[0]->dport_dev) {
>> + dev_dbg(dev, "%s, host bridge does not match\n", __func__);
>> + return 0;
>> + }
> Is this check necessary? I would imagine that there can only be a single
> host bridge above our endpoint since there's also no interleaving?
I guess this is a sanity check. The two variables are given by the
caller, and there exists the possibility of giving the wrong one for any
of them. So I think it is a good idea to keep it.
>> +
>> + /*
>> + * Walk the root decoder resource range relying on cxl_region_rwsem to
>> + * preclude sibling arrival/departure and find the largest free space
>> + * gap.
>> + */
>> + lockdep_assert_held_read(&cxl_region_rwsem);
>> + max = 0;
>> + res = cxlrd->res->child;
>> + if (!res)
>> + max = resource_size(cxlrd->res);
>> + else
>> + max = 0;
>> +
>> + for (prev = NULL; res; prev = res, res = res->sibling) {
>> + struct resource *next = res->sibling;
>> + resource_size_t free = 0;
>> +
>> + if (!prev && res->start > cxlrd->res->start) {
>> + free = res->start - cxlrd->res->start;
>> + max = max(free, max);
>> + }
>> + if (prev && res->start > prev->end + 1) {
>> + free = res->start - prev->end + 1;
>> + max = max(free, max);
>> + }
>> + if (next && res->end + 1 < next->start) {
>> + free = next->start - res->end + 1;
>> + max = max(free, max);
>> + }
>> + if (!next && res->end + 1 < cxlrd->res->end + 1) {
>> + free = cxlrd->res->end + 1 - res->end + 1;
>> + max = max(free, max);
>> + }
>> + }
>> +
>> + dev_dbg(CXLRD_DEV(cxlrd), "%s, found %pa bytes of free space\n",
>> + __func__, &max);
>> + if (max > ctx->max_hpa) {
>> + if (ctx->cxlrd)
>> + put_device(CXLRD_DEV(ctx->cxlrd));
>> + get_device(CXLRD_DEV(cxlrd));
>> + ctx->cxlrd = cxlrd;
>> + ctx->max_hpa = max;
>> + dev_dbg(CXLRD_DEV(cxlrd), "%s, found %pa bytes of free space\n",
>> + __func__, &max);
>> + }
>> + return 0;
>> +}
>> +
>> +/**
>> + * cxl_get_hpa_freespace - find a root decoder with free capacity per constraints
>> + * @endpoint: an endpoint that is mapped by the returned decoder
>> + * @flags: CXL_DECODER_F flags for selecting RAM vs PMEM, and HDM-H vs HDM-D[B]
>> + * @max_avail_contig: output parameter of max contiguous bytes available in the
>> + * returned decoder
>> + *
>> + * The return tuple of a 'struct cxl_root_decoder' and 'bytes available (@max)'
> The (@max) part should be (@max_avail_contig), no?
Right. I'll fix it.
>> + * is a point in time snapshot. If by the time the caller goes to use this root
>> + * decoder's capacity the capacity is reduced then caller needs to loop and
>> + * retry.
>> + *
>> + * The returned root decoder has an elevated reference count that needs to be
>> + * put with put_device(cxlrd_dev(cxlrd)). Locking context is with
>> + * cxl_{acquire,release}_endpoint(), that ensures removal of the root decoder
>> + * does not race.
>> + */
>> +struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
>> + unsigned long flags,
>> + resource_size_t *max_avail_contig)
>> +{
>> + struct cxl_port *endpoint = cxlmd->endpoint;
>> + struct cxlrd_max_context ctx = {
>> + .host_bridge = endpoint->host_bridge,
>> + .flags = flags,
>> + };
>> + struct cxl_port *root_port;
>> + struct cxl_root *root __free(put_cxl_root) = find_cxl_root(endpoint);
>> +
>> + if (!is_cxl_endpoint(endpoint)) {
>> + dev_dbg(&endpoint->dev, "hpa requestor is not an endpoint\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + if (!root) {
>> + dev_dbg(&endpoint->dev, "endpoint can not be related to a root port\n");
> This message makes it seem like there's a problem with the endpoint, not the hierarchy (at least to me).
> Maybe something like "can't find root port associated with endpoint" or "can't find root port above endpoint" instead?
Well, there is a problem for sure, but I can not see why your suggestion
improves things here. It is not easy to really know what is the problem
without a real case triggering it, so IMO blaming one or another is a
blind choice by now.
>> + return ERR_PTR(-ENXIO);
>> + }
>> +
>> + root_port = &root->port;
>> + down_read(&cxl_region_rwsem);
>> + device_for_each_child(&root_port->dev, &ctx, find_max_hpa);
>> + up_read(&cxl_region_rwsem);
>> +
>> + if (!ctx.cxlrd)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + *max_avail_contig = ctx.max_hpa;
>> + return ctx.cxlrd;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_get_hpa_freespace, CXL);
>> +
>> static ssize_t size_store(struct device *dev, struct device_attribute *attr,
>> const char *buf, size_t len)
>> {
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index e5f918be6fe4..1e0e797b9303 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -776,6 +776,9 @@ static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport,
>> struct cxl_decoder *to_cxl_decoder(struct device *dev);
>> struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
>> struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev);
>> +
>> +#define CXLRD_DEV(cxlrd) (&(cxlrd)->cxlsd.cxld.dev)
>> +
>> struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
>> bool is_root_decoder(struct device *dev);
>> bool is_switch_decoder(struct device *dev);
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 5608ed0f5f15..4508b5c186e8 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -7,6 +7,10 @@
>> #include <linux/ioport.h>
>> #include <linux/pci.h>
>>
>> +#define CXL_DECODER_F_RAM BIT(0)
>> +#define CXL_DECODER_F_PMEM BIT(1)
>> +#define CXL_DECODER_F_TYPE2 BIT(2)
>> +
>> enum cxl_resource {
>> CXL_RES_DPA,
>> CXL_RES_RAM,
>> @@ -59,4 +63,8 @@ int cxl_release_resource(struct cxl_dev_state *cxlds, enum cxl_resource type);
>> void cxl_set_media_ready(struct cxl_dev_state *cxlds);
>> struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
>> struct cxl_dev_state *cxlds);
>> +struct cxl_port;
>> +struct cxl_root_decoder *cxl_get_hpa_freespace(struct cxl_memdev *cxlmd,
>> + unsigned long flags,
>> + resource_size_t *max);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 18/27] sfc: get endpoint decoder
2024-11-22 20:45 ` Ben Cheatham
@ 2024-11-27 16:47 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 16:47 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/22/24 20:45, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Use cxl api for getting DPA (Device Physical Address) to use through an
>> endpoint decoder.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/net/ethernet/sfc/efx_cxl.c | 9 +++++++++
>> 1 file changed, 9 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
>> index 048500492371..85d9632f497a 100644
>> --- a/drivers/net/ethernet/sfc/efx_cxl.c
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
>> @@ -120,6 +120,14 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> goto err3;
>> }
>>
>> + cxl->cxled = cxl_request_dpa(cxl->cxlmd, true, EFX_CTPIO_BUFFER_SIZE,
>> + EFX_CTPIO_BUFFER_SIZE);
>> + if (!cxl->cxled || IS_ERR(cxl->cxled)) {
> I'm 99% sure you can replace this with IS_ERR_OR_NULL(cxl->cxled).
Right. I'll change it.
Thanks!
>
>> + pci_err(pci_dev, "CXL accel request DPA failed");
>> + rc = PTR_ERR(cxl->cxlrd);
>> + goto err3;
>> + }
>> +
>> probe_data->cxl = cxl;
>>
>> return 0;
>> @@ -137,6 +145,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> void efx_cxl_exit(struct efx_probe_data *probe_data)
>> {
>> if (probe_data->cxl) {
>> + cxl_dpa_free(probe_data->cxl->cxled);
>> cxl_release_resource(probe_data->cxl->cxlds, CXL_RES_RAM);
>> kfree(probe_data->cxl->cxlds);
>> kfree(probe_data->cxl);
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax
2024-11-22 20:46 ` Ben Cheatham
@ 2024-11-27 16:59 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 16:59 UTC (permalink / raw)
To: Ben Cheatham, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/22/24 20:46, Ben Cheatham wrote:
> On 11/18/24 10:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> By definition a type2 cxl device will use the host managed memory for
>> specific functionality, therefore it should not be available to other
>> uses. However, a dax interface could be just good enough in some cases.
>>
>> Add a flag to a cxl region for specifically state to not create a dax
>> device. Allow a Type2 driver to set that flag at region creation time.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/region.c | 10 +++++++++-
>> drivers/cxl/cxl.h | 3 +++
>> drivers/cxl/cxlmem.h | 3 ++-
>> include/cxl/cxl.h | 3 ++-
>> 4 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index 70549d42c2e3..eff3ad788077 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -3558,7 +3558,8 @@ __construct_new_region(struct cxl_root_decoder *cxlrd,
>> * cxl_region driver.
>> */
>> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled)
>> + struct cxl_endpoint_decoder *cxled,
>> + bool avoid_dax)
>> {
>> struct cxl_region *cxlr;
>>
>> @@ -3574,6 +3575,10 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> drop_region(cxlr);
>> return ERR_PTR(-ENODEV);
>> }
>> +
>> + if (avoid_dax)
>> + set_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags);
>> +
>> return cxlr;
>> }
>> EXPORT_SYMBOL_NS_GPL(cxl_create_region, CXL);
>> @@ -3713,6 +3718,9 @@ static int cxl_region_probe(struct device *dev)
>> case CXL_DECODER_PMEM:
>> return devm_cxl_add_pmem_region(cxlr);
>> case CXL_DECODER_RAM:
>> + if (test_bit(CXL_REGION_F_AVOID_DAX, &cxlr->flags))
>> + return 0;
> I think it's possible for a type 2 device to have pmem as well, and
> it looks like these are the only two options at the moment, so I would
> just move this check to before the switch statement.
Yes, that was also suggested in previous patchsets and I forgot.
I'll do it for v6.
>> +
>> /*
>> * The region can not be manged by CXL if any portion of
>> * it is already online as 'System RAM'
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index 1e0e797b9303..ee3385db5663 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -512,6 +512,9 @@ struct cxl_region_params {
>> */
>> #define CXL_REGION_F_NEEDS_RESET 1
>>
>> +/* Allow Type2 drivers to specify if a dax region should not be created. */
>> +#define CXL_REGION_F_AVOID_DAX 2
>> +
> I would like to see flags such that the device could choose the region type
> (system ram, device-dax, or none). I think that adding the ability
> for device-dax would add a patch or two, so that may be a good follow up
> patch.
Not sure the system ram option makes sense when this code can be executed.
Anyway, as you say, let's leave this for a follow up.
Thanks
>> /**
>> * struct cxl_region - CXL region
>> * @dev: This region's device
>> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
>> index 9d874f1cb3bf..cc2e2a295f3d 100644
>> --- a/drivers/cxl/cxlmem.h
>> +++ b/drivers/cxl/cxlmem.h
>> @@ -875,5 +875,6 @@ struct seq_file;
>> struct dentry *cxl_debugfs_create_dir(const char *dir);
>> void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
>> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled);
>> + struct cxl_endpoint_decoder *cxled,
>> + bool avoid_dax);
>> #endif /* __CXL_MEM_H__ */
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index d295af4f5f9e..2a8ebabfc1dd 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -73,7 +73,8 @@ struct cxl_endpoint_decoder *cxl_request_dpa(struct cxl_memdev *cxlmd,
>> resource_size_t max);
>> int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
>> struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> - struct cxl_endpoint_decoder *cxled);
>> + struct cxl_endpoint_decoder *cxled,
>> + bool avoid_dax);
>>
>> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 26/27] cxl: add function for obtaining params from a region
2024-11-21 16:31 ` Dave Jiang
@ 2024-11-27 17:12 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 17:12 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, martin.habets, edward.cree, davem, kuba, pabeni,
edumazet
On 11/21/24 16:31, Dave Jiang wrote:
>
> On 11/18/24 9:44 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> A CXL region struct contains the physical address to work with.
>>
>> Add a function for given a opaque cxl region struct returns the params
>> to be used for mapping such memory range.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/region.c | 16 ++++++++++++++++
>> drivers/cxl/cxl.h | 2 ++
>> include/cxl/cxl.h | 2 ++
>> 3 files changed, 20 insertions(+)
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index eff3ad788077..fa44a60549f7 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -2663,6 +2663,22 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
>> return ERR_PTR(rc);
>> }
>>
>> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
>> + resource_size_t *end)
> Maybe just pass in a 'struct range' ptr and call it cxl_get_region_range()?
That makes sense, and that solves the problem raised by Allison.
Thanks
> DJ
>
>> +{
>> + if (!region)
>> + return -ENODEV;
>> +
>> + if (!region->params.res)
>> + return -ENOSPC;
>> +
>> + *start = region->params.res->start;
>> + *end = region->params.res->end;
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_get_region_params, CXL);
>> +
>> static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
>> {
>> return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index ee3385db5663..7b46d313e581 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -913,6 +913,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
>>
>> bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
>>
>> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
>> + resource_size_t *end);
>> /*
>> * Unit test builds overrides this to __weak, find the 'strong' version
>> * of these symbols in tools/testing/cxl/.
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 2a8ebabfc1dd..f14a3f292ad8 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -77,4 +77,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> bool avoid_dax);
>>
>> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
>> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
>> + resource_size_t *end);
>> #endif
^ permalink raw reply [flat|nested] 99+ messages in thread
* Re: [PATCH v5 26/27] cxl: add function for obtaining params from a region
2024-11-21 2:56 ` Alison Schofield
@ 2024-11-27 17:18 ` Alejandro Lucero Palau
0 siblings, 0 replies; 99+ messages in thread
From: Alejandro Lucero Palau @ 2024-11-27 17:18 UTC (permalink / raw)
To: Alison Schofield, alejandro.lucero-palau
Cc: linux-cxl, netdev, dan.j.williams, martin.habets, edward.cree,
davem, kuba, pabeni, edumazet
On 11/21/24 02:56, Alison Schofield wrote:
> On Mon, Nov 18, 2024 at 04:44:33PM +0000, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> A CXL region struct contains the physical address to work with.
>>
>> Add a function for given a opaque cxl region struct returns the params
>> to be used for mapping such memory range.
> I may not be understanding what needs to be opaque here.
The driver can not access cxl_region struct just using it in calls, what
requires this patch as other in this patchset as an API for accel drivers.
Apologies if mentioning that here creates confusion.
> Why not just 'add function to get a region resource'
> and then add 'cxl_get_region_resource().
>
> Region params usually refers to the member of struct cxl_region
> that is called 'params' and that includes more than the resource.
I did not realize using params could be problematic, but I agree it is
not how we should refer to what we are returning to the caller.
I think using Dave suggestion for using range instead should solve the
problem.
Thanks
> --Alison
>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/region.c | 16 ++++++++++++++++
>> drivers/cxl/cxl.h | 2 ++
>> include/cxl/cxl.h | 2 ++
>> 3 files changed, 20 insertions(+)
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index eff3ad788077..fa44a60549f7 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -2663,6 +2663,22 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
>> return ERR_PTR(rc);
>> }
>>
>> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
>> + resource_size_t *end)
>> +{
>> + if (!region)
>> + return -ENODEV;
>> +
>> + if (!region->params.res)
>> + return -ENOSPC;
>> +
>> + *start = region->params.res->start;
>> + *end = region->params.res->end;
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_get_region_params, CXL);
>> +
>> static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
>> {
>> return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index ee3385db5663..7b46d313e581 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -913,6 +913,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
>>
>> bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
>>
>> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
>> + resource_size_t *end);
>> /*
>> * Unit test builds overrides this to __weak, find the 'strong' version
>> * of these symbols in tools/testing/cxl/.
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 2a8ebabfc1dd..f14a3f292ad8 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -77,4 +77,6 @@ struct cxl_region *cxl_create_region(struct cxl_root_decoder *cxlrd,
>> bool avoid_dax);
>>
>> int cxl_accel_region_detach(struct cxl_endpoint_decoder *cxled);
>> +int cxl_get_region_params(struct cxl_region *region, resource_size_t *start,
>> + resource_size_t *end);
>> #endif
>> --
>> 2.17.1
>>
>>
^ permalink raw reply [flat|nested] 99+ messages in thread
end of thread, other threads:[~2024-11-27 17:18 UTC | newest]
Thread overview: 99+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-18 16:44 [PATCH v5 00/27] cxl: add type2 device basic support alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 01/27] " alejandro.lucero-palau
2024-11-18 21:55 ` Dave Jiang
2024-11-20 13:40 ` Alejandro Lucero Palau
2024-11-20 23:07 ` Fan Ni
2024-11-22 4:35 ` Alison Schofield
2024-11-22 9:27 ` Alejandro Lucero Palau
2024-11-26 5:59 ` Alison Schofield
2024-11-26 16:38 ` Alejandro Lucero Palau
2024-11-22 20:43 ` Ben Cheatham
2024-11-27 9:00 ` Alejandro Lucero Palau
2024-11-27 9:07 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 02/27] sfc: add cxl support using new CXL API alejandro.lucero-palau
2024-11-22 20:43 ` Ben Cheatham
2024-11-27 9:15 ` Alejandro Lucero Palau
2024-11-26 18:08 ` Fan Ni
2024-11-27 9:17 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 03/27] cxl: add capabilities field to cxl_dev_state and cxl_port alejandro.lucero-palau
2024-11-18 22:52 ` Dave Jiang
2024-11-19 12:28 ` Alejandro Lucero Palau
2024-11-19 15:53 ` Dave Jiang
2024-11-20 13:41 ` Alejandro Lucero Palau
2024-11-22 20:44 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 04/27] cxl/pci: add check for validating capabilities alejandro.lucero-palau
2024-11-22 20:44 ` Ben Cheatham
2024-11-27 11:34 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 05/27] cxl: move pci generic code alejandro.lucero-palau
2024-11-18 22:57 ` Dave Jiang
2024-11-22 20:44 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 06/27] cxl: add function for type2 cxl regs setup alejandro.lucero-palau
2024-11-18 23:32 ` Dave Jiang
2024-11-21 22:34 ` Alison Schofield
2024-11-27 11:46 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 07/27] sfc: use cxl api for regs setup and checking alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 08/27] cxl: add functions for resource request/release by a driver alejandro.lucero-palau
2024-11-22 20:45 ` Ben Cheatham
2024-11-18 16:44 ` [PATCH v5 09/27] sfc: request cxl ram resource alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 10/27] cxl: harden resource_contains checks to handle zero size resources alejandro.lucero-palau
2024-11-19 18:00 ` Dave Jiang
2024-11-20 13:44 ` Alejandro Lucero Palau
2024-11-19 19:50 ` Zhi Wang
2024-11-20 13:45 ` Alejandro Lucero Palau
2024-11-21 7:13 ` Zhi Wang
2024-11-21 2:46 ` Alison Schofield
2024-11-21 9:22 ` Alejandro Lucero Palau
2024-11-21 21:00 ` Alison Schofield
2024-11-27 14:56 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 11/27] cxl: add function for setting media ready by a driver alejandro.lucero-palau
2024-11-19 18:12 ` Dave Jiang
2024-11-22 20:45 ` Ben Cheatham
2024-11-27 15:07 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 12/27] sfc: set cxl media ready alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 13/27] cxl: prepare memdev creation for type2 alejandro.lucero-palau
2024-11-19 18:24 ` Dave Jiang
2024-11-19 20:06 ` Zhi Wang
2024-11-19 21:27 ` Dave Jiang
2024-11-20 13:57 ` Alejandro Lucero Palau
2024-11-20 17:15 ` Dave Jiang
2024-11-21 7:43 ` Zhi Wang
2024-11-22 20:45 ` Ben Cheatham
2024-11-27 16:09 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 14/27] sfc: create type2 cxl memdev alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 15/27] cxl: define a driver interface for HPA free space enumeration alejandro.lucero-palau
2024-11-22 20:45 ` Ben Cheatham
2024-11-27 16:32 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 16/27] sfc: obtain root decoder with enough HPA free space alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 17/27] cxl: define a driver interface for DPA allocation alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 18/27] sfc: get endpoint decoder alejandro.lucero-palau
2024-11-22 20:45 ` Ben Cheatham
2024-11-27 16:47 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 19/27] cxl: make region type based on endpoint type alejandro.lucero-palau
2024-11-19 20:16 ` Zhi Wang
2024-11-21 16:16 ` Dave Jiang
2024-11-18 16:44 ` [PATCH v5 20/27] cxl/region: factor out interleave ways setup alejandro.lucero-palau
2024-11-19 20:20 ` Zhi Wang
2024-11-21 16:23 ` Dave Jiang
2024-11-18 16:44 ` [PATCH v5 21/27] cxl/region: factor out interleave granularity setup alejandro.lucero-palau
2024-11-19 20:23 ` Zhi Wang
2024-11-21 16:24 ` Dave Jiang
2024-11-18 16:44 ` [PATCH v5 22/27] cxl: allow region creation by type2 drivers alejandro.lucero-palau
2024-11-19 20:37 ` Zhi Wang
2024-11-20 13:51 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 23/27] sfc: create cxl region alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 24/27] cxl: add region flag for precluding a device memory to be used for dax alejandro.lucero-palau
2024-11-19 20:39 ` Zhi Wang
2024-11-20 13:55 ` Alejandro Lucero Palau
2024-11-22 20:46 ` Ben Cheatham
2024-11-27 16:59 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 25/27] sfc: specify avoid dax when cxl region is created alejandro.lucero-palau
2024-11-18 16:44 ` [PATCH v5 26/27] cxl: add function for obtaining params from a region alejandro.lucero-palau
2024-11-19 20:40 ` Zhi Wang
2024-11-21 2:56 ` Alison Schofield
2024-11-27 17:18 ` Alejandro Lucero Palau
2024-11-21 16:31 ` Dave Jiang
2024-11-27 17:12 ` Alejandro Lucero Palau
2024-11-18 16:44 ` [PATCH v5 27/27] sfc: support pio mapping based on cxl alejandro.lucero-palau
2024-11-21 3:33 ` [PATCH v5 00/27] cxl: add type2 device basic support Alison Schofield
2024-11-21 9:27 ` Alejandro Lucero Palau
2024-11-22 4:14 ` Alison Schofield
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).