linux-cxl.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cxl: Remove core/acpi.c and cxl core dependency on ACPI
@ 2025-06-05  0:11 Dave Jiang
  2025-06-09 10:38 ` Jonathan Cameron
  2025-06-09 17:03 ` Fabio M. De Francesco
  0 siblings, 2 replies; 14+ messages in thread
From: Dave Jiang @ 2025-06-05  0:11 UTC (permalink / raw)
  To: linux-cxl
  Cc: dave, jonathan.cameron, alison.schofield, vishal.l.verma,
	ira.weiny, dan.j.williams

It was a mistake to introduce core/acpi.c and putting ACPI dependency on
cxl_core when adding the extended linear cache support. Add a callback
in the cxl_root_decoder to retrieve the extended linear cache size from
ACPI via the cxl_acpi driver.

In order to deal with cxl_test, a device parameter had to be introduced
to the hmat_get_extended_linear_cache_size() call in order to help with
the mock wrapped function from ACPI. Even though the 'struct device' is
not used by the actual hmat_get_extended_linear_cache_size() function.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 drivers/acpi/numa/hmat.c      |  4 +++-
 drivers/cxl/acpi.c            | 15 ++++++++++++++-
 drivers/cxl/core/Makefile     |  1 -
 drivers/cxl/core/acpi.c       | 11 -----------
 drivers/cxl/core/core.h       |  2 --
 drivers/cxl/core/port.c       |  5 ++++-
 drivers/cxl/core/region.c     |  6 +++++-
 drivers/cxl/cxl.h             | 12 +++++++++++-
 include/linux/acpi.h          |  6 ++++--
 tools/testing/cxl/Kbuild      |  2 +-
 tools/testing/cxl/test/cxl.c  | 20 ++++++++++++++++++++
 tools/testing/cxl/test/mock.c | 23 +++++++++++++++++++++++
 tools/testing/cxl/test/mock.h |  4 ++++
 13 files changed, 89 insertions(+), 22 deletions(-)
 delete mode 100644 drivers/cxl/core/acpi.c

diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c
index 9d9052258e92..bc8441dc7fe2 100644
--- a/drivers/acpi/numa/hmat.c
+++ b/drivers/acpi/numa/hmat.c
@@ -110,6 +110,7 @@ static struct memory_target *find_mem_target(unsigned int mem_pxm)
 
 /**
  * hmat_get_extended_linear_cache_size - Retrieve the extended linear cache size
+ * @dev: device for debug output
  * @backing_res: resource from the backing media
  * @nid: node id for the memory region
  * @cache_size: (Output) size of extended linear cache.
@@ -117,7 +118,8 @@ static struct memory_target *find_mem_target(unsigned int mem_pxm)
  * Return: 0 on success. Errno on failure.
  *
  */
-int hmat_get_extended_linear_cache_size(struct resource *backing_res, int nid,
+int hmat_get_extended_linear_cache_size(struct device *dev,
+					struct resource *backing_res, int nid,
 					resource_size_t *cache_size)
 {
 	unsigned int pxm = node_to_pxm(nid);
diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index cb14829bb9be..7076d471ada5 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -337,6 +337,19 @@ static int add_or_reset_cxl_resource(struct resource *parent, struct resource *r
 	return rc;
 }
 
+static int cxl_acpi_get_extended_linear_cache_size(struct cxl_root_decoder *cxlrd,
+						   struct resource *backing_res,
+						   int nid,
+						   resource_size_t *size)
+{
+	return hmat_get_extended_linear_cache_size(&cxlrd->cxlsd.cxld.dev,
+						   backing_res, nid, size);
+}
+
+static const struct cxl_rcd_ops acpi_rcd_ops = {
+	.get_extended_linear_cache_size = cxl_acpi_get_extended_linear_cache_size,
+};
+
 DEFINE_FREE(put_cxlrd, struct cxl_root_decoder *,
 	    if (!IS_ERR_OR_NULL(_T)) put_device(&_T->cxlsd.cxld.dev))
 DEFINE_FREE(del_cxl_resource, struct resource *, if (_T) del_cxl_resource(_T))
@@ -375,7 +388,7 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
 		return rc;
 
 	struct cxl_root_decoder *cxlrd __free(put_cxlrd) =
-		cxl_root_decoder_alloc(root_port, ways);
+		cxl_root_decoder_alloc(root_port, ways, &acpi_rcd_ops);
 
 	if (IS_ERR(cxlrd))
 		return PTR_ERR(cxlrd);
diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
index 086df97a0fcf..f67e879dbf9a 100644
--- a/drivers/cxl/core/Makefile
+++ b/drivers/cxl/core/Makefile
@@ -15,7 +15,6 @@ cxl_core-y += hdm.o
 cxl_core-y += pmu.o
 cxl_core-y += cdat.o
 cxl_core-y += ras.o
-cxl_core-y += acpi.o
 cxl_core-$(CONFIG_TRACING) += trace.o
 cxl_core-$(CONFIG_CXL_REGION) += region.o
 cxl_core-$(CONFIG_CXL_MCE) += mce.o
diff --git a/drivers/cxl/core/acpi.c b/drivers/cxl/core/acpi.c
deleted file mode 100644
index f13b4dae6ac5..000000000000
--- a/drivers/cxl/core/acpi.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
-#include <linux/acpi.h>
-#include "cxl.h"
-#include "core.h"
-
-int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
-					    int nid, resource_size_t *size)
-{
-	return hmat_get_extended_linear_cache_size(backing_res, nid, size);
-}
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 17b692eb3257..719cee0de1ec 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -120,8 +120,6 @@ int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
 int cxl_ras_init(void);
 void cxl_ras_exit(void);
 int cxl_gpf_port_setup(struct cxl_dport *dport);
-int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
-					    int nid, resource_size_t *size);
 
 #ifdef CONFIG_CXL_FEATURES
 size_t cxl_get_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 726bd4a7de27..89b4cdc2bd8c 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1800,6 +1800,7 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
  * cxl_root_decoder_alloc - Allocate a root level decoder
  * @port: owning CXL root of this decoder
  * @nr_targets: static number of downstream targets
+ * @ops: root decoder callback operations
  *
  * Return: A new cxl decoder to be registered by cxl_decoder_add(). A
  * 'CXL root' decoder is one that decodes from a top-level / static platform
@@ -1807,7 +1808,8 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
  * topology.
  */
 struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
-						unsigned int nr_targets)
+						unsigned int nr_targets,
+						const struct cxl_rcd_ops *ops)
 {
 	struct cxl_root_decoder *cxlrd;
 	struct cxl_switch_decoder *cxlsd;
@@ -1846,6 +1848,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
 
 	atomic_set(&cxlrd->region_id, rc);
 	cxlrd->qos_class = CXL_QOS_CLASS_INVALID;
+	cxlrd->ops = ops;
 	return cxlrd;
 }
 EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, "CXL");
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index c3f4dc244df7..ac05fe7335c9 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -3239,7 +3239,11 @@ static int cxl_extended_linear_cache_resize(struct cxl_region *cxlr,
 	resource_size_t cache_size, start;
 	int rc;
 
-	rc = cxl_acpi_get_extended_linear_cache_size(res, nid, &cache_size);
+	if (!cxlrd->ops || !cxlrd->ops->get_extended_linear_cache_size)
+		return -EOPNOTSUPP;
+
+	rc = cxlrd->ops->get_extended_linear_cache_size(cxlrd, res, nid,
+							&cache_size);
 	if (rc)
 		return rc;
 
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index a9ab46eb0610..899092835e04 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -420,6 +420,12 @@ struct cxl_switch_decoder {
 struct cxl_root_decoder;
 typedef u64 (*cxl_hpa_to_spa_fn)(struct cxl_root_decoder *cxlrd, u64 hpa);
 
+struct cxl_rcd_ops {
+	int (*get_extended_linear_cache_size)(struct cxl_root_decoder *cxlrd,
+					      struct resource *backing_res,
+					      int nid, resource_size_t *size);
+};
+
 /**
  * struct cxl_root_decoder - Static platform CXL address decoder
  * @res: host / parent resource for region allocations
@@ -428,6 +434,7 @@ typedef u64 (*cxl_hpa_to_spa_fn)(struct cxl_root_decoder *cxlrd, u64 hpa);
  * @platform_data: platform specific configuration data
  * @range_lock: sync region autodiscovery by address range
  * @qos_class: QoS performance class cookie
+ * @ops: root decoder specific operations
  * @cxlsd: base cxl switch decoder
  */
 struct cxl_root_decoder {
@@ -437,7 +444,9 @@ struct cxl_root_decoder {
 	void *platform_data;
 	struct mutex range_lock;
 	int qos_class;
+	const struct cxl_rcd_ops *ops;
 	struct cxl_switch_decoder cxlsd;
+	/* DO NOT ADD ANYTHING AFTER THIS LINE. cxlsd trails with a flex array */
 };
 
 /*
@@ -772,7 +781,8 @@ bool is_root_decoder(struct device *dev);
 bool is_switch_decoder(struct device *dev);
 bool is_endpoint_decoder(struct device *dev);
 struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
-						unsigned int nr_targets);
+						unsigned int nr_targets,
+						const struct cxl_rcd_ops *ops);
 struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
 						    unsigned int nr_targets);
 int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 3f2e93ed9730..507aa15913d2 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1095,10 +1095,12 @@ static inline acpi_handle acpi_get_processor_handle(int cpu)
 #endif	/* !CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_HMAT
-int hmat_get_extended_linear_cache_size(struct resource *backing_res, int nid,
+int hmat_get_extended_linear_cache_size(struct device *dev,
+					struct resource *backing_res, int nid,
 					resource_size_t *size);
 #else
-static inline int hmat_get_extended_linear_cache_size(struct resource *backing_res,
+static inline int hmat_get_extended_linear_cache_size(struct device *dev,
+						      struct resource *backing_res,
 						      int nid, resource_size_t *size)
 {
 	return -EOPNOTSUPP;
diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild
index 387f3df8b988..3e6e3c4ab797 100644
--- a/tools/testing/cxl/Kbuild
+++ b/tools/testing/cxl/Kbuild
@@ -15,6 +15,7 @@ ldflags-y += --wrap=devm_cxl_add_rch_dport
 ldflags-y += --wrap=cxl_rcd_component_reg_phys
 ldflags-y += --wrap=cxl_endpoint_parse_cdat
 ldflags-y += --wrap=cxl_dport_init_ras_reporting
+ldflags-y += --wrap=hmat_get_extended_linear_cache_size
 
 DRIVERS := ../../../drivers
 CXL_SRC := $(DRIVERS)/cxl
@@ -62,7 +63,6 @@ cxl_core-y += $(CXL_CORE_SRC)/hdm.o
 cxl_core-y += $(CXL_CORE_SRC)/pmu.o
 cxl_core-y += $(CXL_CORE_SRC)/cdat.o
 cxl_core-y += $(CXL_CORE_SRC)/ras.o
-cxl_core-y += $(CXL_CORE_SRC)/acpi.o
 cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
 cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o
 cxl_core-$(CONFIG_CXL_MCE) += $(CXL_CORE_SRC)/mce.o
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 1c3336095923..40d9f7b76d01 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -470,6 +470,24 @@ struct cxl_cedt_context {
 	struct device *dev;
 };
 
+static int mock_hmat_get_extended_linear_cache_size(struct device *dev,
+						    struct resource *backing_res,
+						    int nid, resource_size_t *size)
+{
+	struct cxl_decoder *cxld;
+	struct cxl_port *port;
+
+	if (!is_root_decoder(dev))
+		return -EINVAL;
+
+	cxld = to_cxl_decoder(dev);
+	port = to_cxl_port(cxld->dev.parent);
+	if (is_mock_port(&port->dev))
+		return -EOPNOTSUPP;
+
+	return hmat_get_extended_linear_cache_size(dev, backing_res, nid, size);
+}
+
 static int mock_acpi_table_parse_cedt(enum acpi_cedt_type id,
 				      acpi_tbl_entry_handler_arg handler_arg,
 				      void *arg)
@@ -1040,6 +1058,8 @@ static struct cxl_mock_ops cxl_mock_ops = {
 	.devm_cxl_enumerate_decoders = mock_cxl_enumerate_decoders,
 	.cxl_endpoint_parse_cdat = mock_cxl_endpoint_parse_cdat,
 	.list = LIST_HEAD_INIT(cxl_mock_ops.list),
+	.hmat_get_extended_linear_cache_size =
+		mock_hmat_get_extended_linear_cache_size,
 };
 
 static void mock_companion(struct acpi_device *adev, struct device *dev)
diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c
index af2594e4f35d..69aa3deee6c2 100644
--- a/tools/testing/cxl/test/mock.c
+++ b/tools/testing/cxl/test/mock.c
@@ -78,6 +78,29 @@ int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
 }
 EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
 
+int __wrap_hmat_get_extended_linear_cache_size(struct device *dev,
+					       struct resource *backing_res,
+					       int nid,
+					       resource_size_t *size)
+{
+	int index;
+	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
+	int rc;
+
+	if (ops)
+		rc = ops->hmat_get_extended_linear_cache_size(dev,
+							      backing_res, nid,
+							      size);
+	else
+		rc = hmat_get_extended_linear_cache_size(dev, backing_res,
+							 nid, size);
+
+	put_cxl_mock_ops(index);
+
+	return rc;
+}
+EXPORT_SYMBOL_NS_GPL(__wrap_hmat_get_extended_linear_cache_size, "CXL");
+
 acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
 					 acpi_string pathname,
 					 struct acpi_object_list *arguments,
diff --git a/tools/testing/cxl/test/mock.h b/tools/testing/cxl/test/mock.h
index d1b0271d2822..240ad3d3e6f9 100644
--- a/tools/testing/cxl/test/mock.h
+++ b/tools/testing/cxl/test/mock.h
@@ -26,6 +26,10 @@ struct cxl_mock_ops {
 	int (*devm_cxl_enumerate_decoders)(
 		struct cxl_hdm *hdm, struct cxl_endpoint_dvsec_info *info);
 	void (*cxl_endpoint_parse_cdat)(struct cxl_port *port);
+	int (*hmat_get_extended_linear_cache_size)(struct device *dev,
+						   struct resource *backing_res,
+						   int nid,
+						   resource_size_t *size);
 };
 
 void register_cxl_mock_ops(struct cxl_mock_ops *ops);

base-commit: 0ff41df1cb268fc69e703a08a57ee14ae967d0ca
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH] cxl: Remove core/acpi.c and cxl core dependency on ACPI
@ 2025-06-10  0:02 Dave Jiang
  2025-06-10  0:03 ` Dave Jiang
  0 siblings, 1 reply; 14+ messages in thread
From: Dave Jiang @ 2025-06-10  0:02 UTC (permalink / raw)
  To: linux-cxl
  Cc: dave, jonathan.cameron, alison.schofield, vishal.l.verma,
	ira.weiny, dan.j.williams

It was a mistake to introduce core/acpi.c and putting ACPI dependency on
cxl_core when adding the extended linear cache support. Add a callback
in the cxl_root_decoder to retrieve the extended linear cache size from
ACPI via the cxl_acpi driver.

In order to deal with cxl_test, a device parameter had to be introduced
to the hmat_get_extended_linear_cache_size() call in order to help with
the mock wrapped function from ACPI. Even though the 'struct device' is
not used by the actual hmat_get_extended_linear_cache_size() function.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 drivers/acpi/numa/hmat.c      |  4 +++-
 drivers/cxl/acpi.c            | 15 ++++++++++++++-
 drivers/cxl/core/Makefile     |  1 -
 drivers/cxl/core/acpi.c       | 11 -----------
 drivers/cxl/core/core.h       |  2 --
 drivers/cxl/core/port.c       |  5 ++++-
 drivers/cxl/core/region.c     |  6 +++++-
 drivers/cxl/cxl.h             | 12 +++++++++++-
 include/linux/acpi.h          |  6 ++++--
 tools/testing/cxl/Kbuild      |  2 +-
 tools/testing/cxl/test/cxl.c  | 20 ++++++++++++++++++++
 tools/testing/cxl/test/mock.c | 23 +++++++++++++++++++++++
 tools/testing/cxl/test/mock.h |  4 ++++
 13 files changed, 89 insertions(+), 22 deletions(-)
 delete mode 100644 drivers/cxl/core/acpi.c

diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c
index 9d9052258e92..bc8441dc7fe2 100644
--- a/drivers/acpi/numa/hmat.c
+++ b/drivers/acpi/numa/hmat.c
@@ -110,6 +110,7 @@ static struct memory_target *find_mem_target(unsigned int mem_pxm)
 
 /**
  * hmat_get_extended_linear_cache_size - Retrieve the extended linear cache size
+ * @dev: device for debug output
  * @backing_res: resource from the backing media
  * @nid: node id for the memory region
  * @cache_size: (Output) size of extended linear cache.
@@ -117,7 +118,8 @@ static struct memory_target *find_mem_target(unsigned int mem_pxm)
  * Return: 0 on success. Errno on failure.
  *
  */
-int hmat_get_extended_linear_cache_size(struct resource *backing_res, int nid,
+int hmat_get_extended_linear_cache_size(struct device *dev,
+					struct resource *backing_res, int nid,
 					resource_size_t *cache_size)
 {
 	unsigned int pxm = node_to_pxm(nid);
diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index cb14829bb9be..7076d471ada5 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -337,6 +337,19 @@ static int add_or_reset_cxl_resource(struct resource *parent, struct resource *r
 	return rc;
 }
 
+static int cxl_acpi_get_extended_linear_cache_size(struct cxl_root_decoder *cxlrd,
+						   struct resource *backing_res,
+						   int nid,
+						   resource_size_t *size)
+{
+	return hmat_get_extended_linear_cache_size(&cxlrd->cxlsd.cxld.dev,
+						   backing_res, nid, size);
+}
+
+static const struct cxl_rcd_ops acpi_rcd_ops = {
+	.get_extended_linear_cache_size = cxl_acpi_get_extended_linear_cache_size,
+};
+
 DEFINE_FREE(put_cxlrd, struct cxl_root_decoder *,
 	    if (!IS_ERR_OR_NULL(_T)) put_device(&_T->cxlsd.cxld.dev))
 DEFINE_FREE(del_cxl_resource, struct resource *, if (_T) del_cxl_resource(_T))
@@ -375,7 +388,7 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
 		return rc;
 
 	struct cxl_root_decoder *cxlrd __free(put_cxlrd) =
-		cxl_root_decoder_alloc(root_port, ways);
+		cxl_root_decoder_alloc(root_port, ways, &acpi_rcd_ops);
 
 	if (IS_ERR(cxlrd))
 		return PTR_ERR(cxlrd);
diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
index 086df97a0fcf..f67e879dbf9a 100644
--- a/drivers/cxl/core/Makefile
+++ b/drivers/cxl/core/Makefile
@@ -15,7 +15,6 @@ cxl_core-y += hdm.o
 cxl_core-y += pmu.o
 cxl_core-y += cdat.o
 cxl_core-y += ras.o
-cxl_core-y += acpi.o
 cxl_core-$(CONFIG_TRACING) += trace.o
 cxl_core-$(CONFIG_CXL_REGION) += region.o
 cxl_core-$(CONFIG_CXL_MCE) += mce.o
diff --git a/drivers/cxl/core/acpi.c b/drivers/cxl/core/acpi.c
deleted file mode 100644
index f13b4dae6ac5..000000000000
--- a/drivers/cxl/core/acpi.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
-#include <linux/acpi.h>
-#include "cxl.h"
-#include "core.h"
-
-int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
-					    int nid, resource_size_t *size)
-{
-	return hmat_get_extended_linear_cache_size(backing_res, nid, size);
-}
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 17b692eb3257..719cee0de1ec 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -120,8 +120,6 @@ int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
 int cxl_ras_init(void);
 void cxl_ras_exit(void);
 int cxl_gpf_port_setup(struct cxl_dport *dport);
-int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
-					    int nid, resource_size_t *size);
 
 #ifdef CONFIG_CXL_FEATURES
 size_t cxl_get_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 726bd4a7de27..89b4cdc2bd8c 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1800,6 +1800,7 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
  * cxl_root_decoder_alloc - Allocate a root level decoder
  * @port: owning CXL root of this decoder
  * @nr_targets: static number of downstream targets
+ * @ops: root decoder callback operations
  *
  * Return: A new cxl decoder to be registered by cxl_decoder_add(). A
  * 'CXL root' decoder is one that decodes from a top-level / static platform
@@ -1807,7 +1808,8 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
  * topology.
  */
 struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
-						unsigned int nr_targets)
+						unsigned int nr_targets,
+						const struct cxl_rcd_ops *ops)
 {
 	struct cxl_root_decoder *cxlrd;
 	struct cxl_switch_decoder *cxlsd;
@@ -1846,6 +1848,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
 
 	atomic_set(&cxlrd->region_id, rc);
 	cxlrd->qos_class = CXL_QOS_CLASS_INVALID;
+	cxlrd->ops = ops;
 	return cxlrd;
 }
 EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, "CXL");
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index c3f4dc244df7..ac05fe7335c9 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -3239,7 +3239,11 @@ static int cxl_extended_linear_cache_resize(struct cxl_region *cxlr,
 	resource_size_t cache_size, start;
 	int rc;
 
-	rc = cxl_acpi_get_extended_linear_cache_size(res, nid, &cache_size);
+	if (!cxlrd->ops || !cxlrd->ops->get_extended_linear_cache_size)
+		return -EOPNOTSUPP;
+
+	rc = cxlrd->ops->get_extended_linear_cache_size(cxlrd, res, nid,
+							&cache_size);
 	if (rc)
 		return rc;
 
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index a9ab46eb0610..899092835e04 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -420,6 +420,12 @@ struct cxl_switch_decoder {
 struct cxl_root_decoder;
 typedef u64 (*cxl_hpa_to_spa_fn)(struct cxl_root_decoder *cxlrd, u64 hpa);
 
+struct cxl_rcd_ops {
+	int (*get_extended_linear_cache_size)(struct cxl_root_decoder *cxlrd,
+					      struct resource *backing_res,
+					      int nid, resource_size_t *size);
+};
+
 /**
  * struct cxl_root_decoder - Static platform CXL address decoder
  * @res: host / parent resource for region allocations
@@ -428,6 +434,7 @@ typedef u64 (*cxl_hpa_to_spa_fn)(struct cxl_root_decoder *cxlrd, u64 hpa);
  * @platform_data: platform specific configuration data
  * @range_lock: sync region autodiscovery by address range
  * @qos_class: QoS performance class cookie
+ * @ops: root decoder specific operations
  * @cxlsd: base cxl switch decoder
  */
 struct cxl_root_decoder {
@@ -437,7 +444,9 @@ struct cxl_root_decoder {
 	void *platform_data;
 	struct mutex range_lock;
 	int qos_class;
+	const struct cxl_rcd_ops *ops;
 	struct cxl_switch_decoder cxlsd;
+	/* DO NOT ADD ANYTHING AFTER THIS LINE. cxlsd trails with a flex array */
 };
 
 /*
@@ -772,7 +781,8 @@ bool is_root_decoder(struct device *dev);
 bool is_switch_decoder(struct device *dev);
 bool is_endpoint_decoder(struct device *dev);
 struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
-						unsigned int nr_targets);
+						unsigned int nr_targets,
+						const struct cxl_rcd_ops *ops);
 struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
 						    unsigned int nr_targets);
 int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 3f2e93ed9730..507aa15913d2 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1095,10 +1095,12 @@ static inline acpi_handle acpi_get_processor_handle(int cpu)
 #endif	/* !CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_HMAT
-int hmat_get_extended_linear_cache_size(struct resource *backing_res, int nid,
+int hmat_get_extended_linear_cache_size(struct device *dev,
+					struct resource *backing_res, int nid,
 					resource_size_t *size);
 #else
-static inline int hmat_get_extended_linear_cache_size(struct resource *backing_res,
+static inline int hmat_get_extended_linear_cache_size(struct device *dev,
+						      struct resource *backing_res,
 						      int nid, resource_size_t *size)
 {
 	return -EOPNOTSUPP;
diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild
index 387f3df8b988..3e6e3c4ab797 100644
--- a/tools/testing/cxl/Kbuild
+++ b/tools/testing/cxl/Kbuild
@@ -15,6 +15,7 @@ ldflags-y += --wrap=devm_cxl_add_rch_dport
 ldflags-y += --wrap=cxl_rcd_component_reg_phys
 ldflags-y += --wrap=cxl_endpoint_parse_cdat
 ldflags-y += --wrap=cxl_dport_init_ras_reporting
+ldflags-y += --wrap=hmat_get_extended_linear_cache_size
 
 DRIVERS := ../../../drivers
 CXL_SRC := $(DRIVERS)/cxl
@@ -62,7 +63,6 @@ cxl_core-y += $(CXL_CORE_SRC)/hdm.o
 cxl_core-y += $(CXL_CORE_SRC)/pmu.o
 cxl_core-y += $(CXL_CORE_SRC)/cdat.o
 cxl_core-y += $(CXL_CORE_SRC)/ras.o
-cxl_core-y += $(CXL_CORE_SRC)/acpi.o
 cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
 cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o
 cxl_core-$(CONFIG_CXL_MCE) += $(CXL_CORE_SRC)/mce.o
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 1c3336095923..40d9f7b76d01 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -470,6 +470,24 @@ struct cxl_cedt_context {
 	struct device *dev;
 };
 
+static int mock_hmat_get_extended_linear_cache_size(struct device *dev,
+						    struct resource *backing_res,
+						    int nid, resource_size_t *size)
+{
+	struct cxl_decoder *cxld;
+	struct cxl_port *port;
+
+	if (!is_root_decoder(dev))
+		return -EINVAL;
+
+	cxld = to_cxl_decoder(dev);
+	port = to_cxl_port(cxld->dev.parent);
+	if (is_mock_port(&port->dev))
+		return -EOPNOTSUPP;
+
+	return hmat_get_extended_linear_cache_size(dev, backing_res, nid, size);
+}
+
 static int mock_acpi_table_parse_cedt(enum acpi_cedt_type id,
 				      acpi_tbl_entry_handler_arg handler_arg,
 				      void *arg)
@@ -1040,6 +1058,8 @@ static struct cxl_mock_ops cxl_mock_ops = {
 	.devm_cxl_enumerate_decoders = mock_cxl_enumerate_decoders,
 	.cxl_endpoint_parse_cdat = mock_cxl_endpoint_parse_cdat,
 	.list = LIST_HEAD_INIT(cxl_mock_ops.list),
+	.hmat_get_extended_linear_cache_size =
+		mock_hmat_get_extended_linear_cache_size,
 };
 
 static void mock_companion(struct acpi_device *adev, struct device *dev)
diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c
index af2594e4f35d..69aa3deee6c2 100644
--- a/tools/testing/cxl/test/mock.c
+++ b/tools/testing/cxl/test/mock.c
@@ -78,6 +78,29 @@ int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
 }
 EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
 
+int __wrap_hmat_get_extended_linear_cache_size(struct device *dev,
+					       struct resource *backing_res,
+					       int nid,
+					       resource_size_t *size)
+{
+	int index;
+	struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
+	int rc;
+
+	if (ops)
+		rc = ops->hmat_get_extended_linear_cache_size(dev,
+							      backing_res, nid,
+							      size);
+	else
+		rc = hmat_get_extended_linear_cache_size(dev, backing_res,
+							 nid, size);
+
+	put_cxl_mock_ops(index);
+
+	return rc;
+}
+EXPORT_SYMBOL_NS_GPL(__wrap_hmat_get_extended_linear_cache_size, "CXL");
+
 acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
 					 acpi_string pathname,
 					 struct acpi_object_list *arguments,
diff --git a/tools/testing/cxl/test/mock.h b/tools/testing/cxl/test/mock.h
index d1b0271d2822..240ad3d3e6f9 100644
--- a/tools/testing/cxl/test/mock.h
+++ b/tools/testing/cxl/test/mock.h
@@ -26,6 +26,10 @@ struct cxl_mock_ops {
 	int (*devm_cxl_enumerate_decoders)(
 		struct cxl_hdm *hdm, struct cxl_endpoint_dvsec_info *info);
 	void (*cxl_endpoint_parse_cdat)(struct cxl_port *port);
+	int (*hmat_get_extended_linear_cache_size)(struct device *dev,
+						   struct resource *backing_res,
+						   int nid,
+						   resource_size_t *size);
 };
 
 void register_cxl_mock_ops(struct cxl_mock_ops *ops);

base-commit: 0ff41df1cb268fc69e703a08a57ee14ae967d0ca
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH] cxl: Remove core/acpi.c and cxl core dependency on ACPI
@ 2025-07-11 15:15 Robert Richter
  2025-07-11 15:40 ` Dave Jiang
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Robert Richter @ 2025-07-11 15:15 UTC (permalink / raw)
  To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield,
	Vishal Verma, Ira Weiny, Dan Williams
  Cc: Robert Richter, linux-kernel, linux-cxl

From Dave [1]:

"""
It was a mistake to introduce core/acpi.c and putting ACPI dependency on
cxl_core when adding the extended linear cache support.
"""

Current implementation calls hmat_get_extended_linear_cache_size() of
the ACPI subsystem. That external reference causes issue running
cxl_test as there is no way to "mock" that function and ignore it when
using cxl test.

Instead of working around that using cxlrd ops and extensively
expanding cxl_test code [1], just move HMAT calls out of the core
module to cxl_acpi. Implement this by adding a @cache_size member to
struct cxl_root_decoder. During initialization the cache size is
determined and added to the root decoder object in cxl_acpi. Later on
in cxl_core the cache_size parameter is used to setup extended linear
caching.

[1] https://patch.msgid.link/20250610172938.139428-1-dave.jiang@intel.com

Cc: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Robert Richter <rrichter@amd.com>
---
 drivers/cxl/acpi.c        | 59 +++++++++++++++++++++++++++++++++++++++
 drivers/cxl/core/Makefile |  1 -
 drivers/cxl/core/acpi.c   | 11 --------
 drivers/cxl/core/core.h   |  2 --
 drivers/cxl/core/region.c |  7 +----
 drivers/cxl/cxl.h         |  1 +
 6 files changed, 61 insertions(+), 20 deletions(-)
 delete mode 100644 drivers/cxl/core/acpi.c

diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index a1a99ec3f12c..712624cba2b6 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -335,6 +335,63 @@ static int add_or_reset_cxl_resource(struct resource *parent, struct resource *r
 	return rc;
 }
 
+static int cxl_acpi_set_cache_size(struct cxl_root_decoder *cxlrd)
+{
+	struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
+	struct range *hpa = &cxld->hpa_range;
+	resource_size_t size = range_len(hpa);
+	resource_size_t start = hpa->start;
+	resource_size_t cache_size;
+	struct resource res;
+	int nid, rc;
+
+	res = DEFINE_RES(start, size, 0);
+	nid = phys_to_target_node(start);
+
+	rc = hmat_get_extended_linear_cache_size(&res, nid, &cache_size);
+	if (rc)
+		return rc;
+
+	/*
+	 * The cache range is expected to be within the CFMWS.
+	 * Currently there is only support cache_size == cxl_size. CXL
+	 * size is then half of the total CFMWS window size.
+	 */
+	size = size >> 1;
+	if (cache_size && size != cache_size) {
+		dev_warn(&cxld->dev,
+			 "Extended Linear Cache size %pa != CXL size %pa. No Support!",
+			 &cache_size, &size);
+		return -ENXIO;
+	}
+
+	cxlrd->cache_size = cache_size;
+
+	return 0;
+}
+
+static void cxl_setup_extended_linear_cache(struct cxl_root_decoder *cxlrd)
+{
+	int rc;
+
+	rc = cxl_acpi_set_cache_size(cxlrd);
+	if (!rc)
+		return;
+
+	if (rc != -EOPNOTSUPP) {
+		/*
+		 * Failing to support extended linear cache region resize does not
+		 * prevent the region from functioning. Only causes cxl list showing
+		 * incorrect region size.
+		 */
+		dev_warn(cxlrd->cxlsd.cxld.dev.parent,
+			 "Extended linear cache calculation failed rc:%d\n", rc);
+	}
+
+	/* Ignoring return code */
+	cxlrd->cache_size = 0;
+}
+
 DEFINE_FREE(put_cxlrd, struct cxl_root_decoder *,
 	    if (!IS_ERR_OR_NULL(_T)) put_device(&_T->cxlsd.cxld.dev))
 DEFINE_FREE(del_cxl_resource, struct resource *, if (_T) del_cxl_resource(_T))
@@ -394,6 +451,8 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
 		ig = CXL_DECODER_MIN_GRANULARITY;
 	cxld->interleave_granularity = ig;
 
+	cxl_setup_extended_linear_cache(cxlrd);
+
 	if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR) {
 		if (ways != 1 && ways != 3) {
 			cxims_ctx = (struct cxl_cxims_context) {
diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
index 79e2ef81fde8..5ad8fef210b5 100644
--- a/drivers/cxl/core/Makefile
+++ b/drivers/cxl/core/Makefile
@@ -15,7 +15,6 @@ cxl_core-y += hdm.o
 cxl_core-y += pmu.o
 cxl_core-y += cdat.o
 cxl_core-y += ras.o
-cxl_core-y += acpi.o
 cxl_core-$(CONFIG_TRACING) += trace.o
 cxl_core-$(CONFIG_CXL_REGION) += region.o
 cxl_core-$(CONFIG_CXL_MCE) += mce.o
diff --git a/drivers/cxl/core/acpi.c b/drivers/cxl/core/acpi.c
deleted file mode 100644
index f13b4dae6ac5..000000000000
--- a/drivers/cxl/core/acpi.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
-#include <linux/acpi.h>
-#include "cxl.h"
-#include "core.h"
-
-int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
-					    int nid, resource_size_t *size)
-{
-	return hmat_get_extended_linear_cache_size(backing_res, nid, size);
-}
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 29b61828a847..9462aea9ce9d 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -120,8 +120,6 @@ int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
 int cxl_ras_init(void);
 void cxl_ras_exit(void);
 int cxl_gpf_port_setup(struct cxl_dport *dport);
-int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
-					    int nid, resource_size_t *size);
 
 #ifdef CONFIG_CXL_FEATURES
 struct cxl_feat_entry *
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 6e5e1460068d..bc542a7142c0 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -3282,15 +3282,10 @@ static int cxl_extended_linear_cache_resize(struct cxl_region *cxlr,
 {
 	struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
 	struct cxl_region_params *p = &cxlr->params;
-	int nid = phys_to_target_node(res->start);
 	resource_size_t size = resource_size(res);
 	resource_size_t cache_size, start;
-	int rc;
-
-	rc = cxl_acpi_get_extended_linear_cache_size(res, nid, &cache_size);
-	if (rc)
-		return rc;
 
+	cache_size = cxlrd->cache_size;
 	if (!cache_size)
 		return 0;
 
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index e7b66ca1d423..4643a95ca111 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -432,6 +432,7 @@ typedef u64 (*cxl_hpa_to_spa_fn)(struct cxl_root_decoder *cxlrd, u64 hpa);
  */
 struct cxl_root_decoder {
 	struct resource *res;
+	resource_size_t cache_size;
 	atomic_t region_id;
 	cxl_hpa_to_spa_fn hpa_to_spa;
 	void *platform_data;
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-07-15 10:14 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-05  0:11 [PATCH] cxl: Remove core/acpi.c and cxl core dependency on ACPI Dave Jiang
2025-06-09 10:38 ` Jonathan Cameron
2025-06-09 15:10   ` Dave Jiang
2025-06-09 17:03 ` Fabio M. De Francesco
2025-06-09 23:59   ` Dave Jiang
  -- strict thread matches above, loose matches on Subject: below --
2025-06-10  0:02 Dave Jiang
2025-06-10  0:03 ` Dave Jiang
2025-07-11 15:15 Robert Richter
2025-07-11 15:40 ` Dave Jiang
2025-07-11 16:36 ` Jonathan Cameron
2025-07-11 18:30 ` Alison Schofield
2025-07-14 21:36 ` Dave Jiang
2025-07-14 23:51   ` Dave Jiang
2025-07-15 10:14     ` Robert Richter

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).