[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250715180407.47426-7-Smita.KoralahalliChannabasappa@amd.com>
Date: Tue, 15 Jul 2025 18:04:06 +0000
From: Smita Koralahalli <Smita.KoralahalliChannabasappa@....com>
To: <linux-cxl@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
<nvdimm@...ts.linux.dev>, <linux-fsdevel@...r.kernel.org>,
<linux-pm@...r.kernel.org>
CC: Davidlohr Bueso <dave@...olabs.net>, Jonathan Cameron
<jonathan.cameron@...wei.com>, Dave Jiang <dave.jiang@...el.com>, "Alison
Schofield" <alison.schofield@...el.com>, Vishal Verma
<vishal.l.verma@...el.com>, Ira Weiny <ira.weiny@...el.com>, Dan Williams
<dan.j.williams@...el.com>, Matthew Wilcox <willy@...radead.org>, Jan Kara
<jack@...e.cz>, "Rafael J . Wysocki" <rafael@...nel.org>, Len Brown
<len.brown@...el.com>, Pavel Machek <pavel@...nel.org>, Li Ming
<ming.li@...omail.com>, Jeff Johnson <jeff.johnson@....qualcomm.com>, "Ying
Huang" <huang.ying.caritas@...il.com>, Yao Xingtao <yaoxt.fnst@...itsu.com>,
Peter Zijlstra <peterz@...radead.org>, Greg KH <gregkh@...uxfoundation.org>,
Nathan Fontenot <nathan.fontenot@....com>, Smita Koralahalli
<Smita.KoralahalliChannabasappa@....com>, Terry Bowman
<terry.bowman@....com>, Robert Richter <rrichter@....com>, Benjamin Cheatham
<benjamin.cheatham@....com>, PradeepVineshReddy Kodamati
<PradeepVineshReddy.Kodamati@....com>, Zhijian Li <lizhijian@...itsu.com>
Subject: [PATCH v5 6/7] dax/hmem, cxl: Defer DAX consumption of SOFT RESERVED resources until after CXL region creation
Introduce a fallback registration mechanism in the DAX HMEM driver to
enable deferred registration of SOFT RESERVED regions. This allows
coordination with the CXL subsystem to avoid conflicts during CXL region
setup.
When CONFIG_CXL_ACPI is enabled, the DAX HMEM driver and HMAT skips
walking SOFT RESERVED resources. Instead, DAX driver provides a
fallback registration mechanism via hmem_register_fallback_handler()
and hmem_fallback_register_device().
The CXL driver invokes hmem_fallback_register_device() after trimming soft
reserves to register any remaining SOFT RESERVED regions that are not
consumed by CXL. This ensures that the DAX driver does not consume
memory ranges that are intended to be part of CXL regions.
Co-developed-by: Nathan Fontenot <Nathan.Fontenot@....com>
Signed-off-by: Nathan Fontenot <Nathan.Fontenot@....com>
Co-developed-by: Terry Bowman <terry.bowman@....com>
Signed-off-by: Terry Bowman <terry.bowman@....com>
Signed-off-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@....com>
---
drivers/acpi/numa/hmat.c | 4 ++++
drivers/cxl/core/region.c | 11 +++++++++
drivers/dax/hmem/Makefile | 1 +
drivers/dax/hmem/device.c | 43 +++++++++++++++++-----------------
drivers/dax/hmem/hmem.c | 6 +++++
drivers/dax/hmem/hmem_notify.c | 27 +++++++++++++++++++++
include/linux/dax.h | 2 ++
7 files changed, 73 insertions(+), 21 deletions(-)
create mode 100644 drivers/dax/hmem/hmem_notify.c
diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c
index 9d9052258e92..8883fd4a229b 100644
--- a/drivers/acpi/numa/hmat.c
+++ b/drivers/acpi/numa/hmat.c
@@ -901,6 +901,10 @@ static void hmat_register_target_devices(struct memory_target *target)
if (!IS_ENABLED(CONFIG_DEV_DAX_HMEM))
return;
+ /* Allow CXL to manage the dax devices if enabled */
+ if (IS_ENABLED(CONFIG_CXL_ACPI))
+ return;
+
for (res = target->memregions.child; res; res = res->sibling) {
int target_nid = pxm_to_node(target->memory_pxm);
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 95951a1f1cab..b1fa38e0b987 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -10,6 +10,7 @@
#include <linux/sort.h>
#include <linux/idr.h>
#include <linux/memory-tiers.h>
+#include <linux/dax.h>
#include <cxlmem.h>
#include <cxl.h>
#include "core.h"
@@ -3603,10 +3604,20 @@ static int cxl_region_softreserv_update_cb(struct device *dev, void *data)
return 0;
}
+static int cxl_softreserv_mem_register(struct resource *res, void *unused)
+{
+ hmem_fallback_register_device(phys_to_target_node(res->start), res);
+ return 0;
+}
+
void cxl_region_softreserv_update(void)
{
bus_for_each_dev(&cxl_bus_type, NULL, NULL,
cxl_region_softreserv_update_cb);
+
+ /* Now register any remaining SOFT RESERVES with DAX */
+ walk_iomem_res_desc(IORES_DESC_SOFT_RESERVED, IORESOURCE_MEM,
+ 0, -1, NULL, cxl_softreserv_mem_register);
}
EXPORT_SYMBOL_NS_GPL(cxl_region_softreserv_update, "CXL");
diff --git a/drivers/dax/hmem/Makefile b/drivers/dax/hmem/Makefile
index d4c4cd6bccd7..aa8742e20408 100644
--- a/drivers/dax/hmem/Makefile
+++ b/drivers/dax/hmem/Makefile
@@ -2,6 +2,7 @@
# device_hmem.o deliberately precedes dax_hmem.o for initcall ordering
obj-$(CONFIG_DEV_DAX_HMEM_DEVICES) += device_hmem.o
obj-$(CONFIG_DEV_DAX_HMEM) += dax_hmem.o
+obj-y += hmem_notify.o
device_hmem-y := device.o
dax_hmem-y := hmem.o
diff --git a/drivers/dax/hmem/device.c b/drivers/dax/hmem/device.c
index 59ad44761191..cc1ed7bbdb1a 100644
--- a/drivers/dax/hmem/device.c
+++ b/drivers/dax/hmem/device.c
@@ -8,7 +8,6 @@
static bool nohmem;
module_param_named(disable, nohmem, bool, 0444);
-static bool platform_initialized;
static DEFINE_MUTEX(hmem_resource_lock);
static struct resource hmem_active = {
.name = "HMEM devices",
@@ -35,9 +34,7 @@ EXPORT_SYMBOL_GPL(walk_hmem_resources);
static void __hmem_register_resource(int target_nid, struct resource *res)
{
- struct platform_device *pdev;
struct resource *new;
- int rc;
new = __request_region(&hmem_active, res->start, resource_size(res), "",
0);
@@ -47,21 +44,6 @@ static void __hmem_register_resource(int target_nid, struct resource *res)
}
new->desc = target_nid;
-
- if (platform_initialized)
- return;
-
- pdev = platform_device_alloc("hmem_platform", 0);
- if (!pdev) {
- pr_err_once("failed to register device-dax hmem_platform device\n");
- return;
- }
-
- rc = platform_device_add(pdev);
- if (rc)
- platform_device_put(pdev);
- else
- platform_initialized = true;
}
void hmem_register_resource(int target_nid, struct resource *res)
@@ -83,9 +65,28 @@ static __init int hmem_register_one(struct resource *res, void *data)
static __init int hmem_init(void)
{
- walk_iomem_res_desc(IORES_DESC_SOFT_RESERVED,
- IORESOURCE_MEM, 0, -1, NULL, hmem_register_one);
- return 0;
+ struct platform_device *pdev;
+ int rc;
+
+ if (!IS_ENABLED(CONFIG_CXL_ACPI)) {
+ walk_iomem_res_desc(IORES_DESC_SOFT_RESERVED,
+ IORESOURCE_MEM, 0, -1, NULL,
+ hmem_register_one);
+ }
+
+ pdev = platform_device_alloc("hmem_platform", 0);
+ if (!pdev) {
+ pr_err("failed to register device-dax hmem_platform device\n");
+ return -1;
+ }
+
+ rc = platform_device_add(pdev);
+ if (rc) {
+ pr_err("failed to add device-dax hmem_platform device\n");
+ platform_device_put(pdev);
+ }
+
+ return rc;
}
/*
diff --git a/drivers/dax/hmem/hmem.c b/drivers/dax/hmem/hmem.c
index 3aedef5f1be1..16873ae0a53b 100644
--- a/drivers/dax/hmem/hmem.c
+++ b/drivers/dax/hmem/hmem.c
@@ -128,6 +128,12 @@ static int hmem_register_device(int target_nid, const struct resource *res)
static int dax_hmem_platform_probe(struct platform_device *pdev)
{
dax_hmem_pdev = pdev;
+
+ if (IS_ENABLED(CONFIG_CXL_ACPI)) {
+ hmem_register_fallback_handler(hmem_register_device);
+ return 0;
+ }
+
return walk_hmem_resources(hmem_register_device);
}
diff --git a/drivers/dax/hmem/hmem_notify.c b/drivers/dax/hmem/hmem_notify.c
new file mode 100644
index 000000000000..1b366ffbda66
--- /dev/null
+++ b/drivers/dax/hmem/hmem_notify.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2025 AMD Corporation. All rights reserved. */
+
+#include <linux/spinlock.h>
+#include <linux/dax.h>
+
+static walk_hmem_fn hmem_fallback_fn;
+static DEFINE_SPINLOCK(hmem_notify_lock);
+
+void hmem_register_fallback_handler(walk_hmem_fn hmem_fn)
+{
+ guard(spinlock_irqsave)(&hmem_notify_lock);
+ hmem_fallback_fn = hmem_fn;
+}
+EXPORT_SYMBOL_GPL(hmem_register_fallback_handler);
+
+void hmem_fallback_register_device(int target_nid, const struct resource *res)
+{
+ walk_hmem_fn hmem_fn;
+
+ guard(spinlock)(&hmem_notify_lock);
+ hmem_fn = hmem_fallback_fn;
+
+ if (hmem_fn)
+ hmem_fn(target_nid, res);
+}
+EXPORT_SYMBOL_GPL(hmem_fallback_register_device);
diff --git a/include/linux/dax.h b/include/linux/dax.h
index a4ad3708ea35..069ded715e5a 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -307,4 +307,6 @@ static inline void hmem_register_resource(int target_nid, struct resource *r)
typedef int (*walk_hmem_fn)(int target_nid, const struct resource *res);
int walk_hmem_resources(walk_hmem_fn fn);
+void hmem_register_fallback_handler(walk_hmem_fn hmem_fn);
+void hmem_fallback_register_device(int target_nid, const struct resource *res);
#endif
--
2.17.1
Powered by blists - more mailing lists