[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260112163514.2551809-6-gourry@gourry.net>
Date: Mon, 12 Jan 2026 11:35:13 -0500
From: Gregory Price <gourry@...rry.net>
To: linux-cxl@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
kernel-team@...a.com,
dave@...olabs.net,
jonathan.cameron@...wei.com,
dave.jiang@...el.com,
alison.schofield@...el.com,
vishal.l.verma@...el.com,
ira.weiny@...el.com,
dan.j.williams@...el.com
Subject: [PATCH 5/6] cxl: add CXL_REGION_SYSRAM_DEFAULT_* build options
DEFAULT_OFFLINE: Blocks will be offline after being created.
DEFAULT_ONLINE: Blocks will be onlined in ZONE_MOVABLE
DEFAULT_ONLINE_NORMAL: Blocks will be onliend in ZONE_NORMAL.
This prevents users from having to use the MHP auto-online build config,
which may cause misbehaviors with other devices hotplugging memory.
Signed-off-by: Gregory Price <gourry@...rry.net>
---
drivers/cxl/Kconfig | 40 ++++++++++
drivers/cxl/core/memctrl/sysram_region.c | 94 ++++++++++++++++++------
2 files changed, 110 insertions(+), 24 deletions(-)
diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig
index 5aed1524f8f1..3e087c9d5ea7 100644
--- a/drivers/cxl/Kconfig
+++ b/drivers/cxl/Kconfig
@@ -243,6 +243,46 @@ config CXL_REGION_CTRL_AUTO_SYSRAM
endchoice
+choice
+ prompt "CXL SYSRAM Auto Online Mode"
+ depends on CXL_REGION
+ default CXL_REGION_SYSRAM_DEFAULT_OFFLINE
+ help
+ Select whether CXL memory hotplugged as System RAM should be
+ automatically onlined and in which zone. This applies when the
+ region controller is set to SYSRAM (either explicitly or via
+ the auto control mode).
+
+config CXL_REGION_SYSRAM_DEFAULT_OFFLINE
+ bool "Offline"
+ help
+ Leave the memory offline after hotplug. The memory must be
+ manually onlined via sysfs or other mechanisms before it can
+ be used by the system.
+
+ This is the default and most conservative option.
+
+config CXL_REGION_SYSRAM_DEFAULT_ONLINE
+ bool "Online (Movable)"
+ help
+ Automatically online the memory as ZONE_MOVABLE after hotplug.
+ ZONE_MOVABLE memory can be used for user pages and is eligible
+ for memory hotremove, but cannot be used for kernel allocations.
+
+ Select this for memory that may need to be hotremoved later.
+
+config CXL_REGION_SYSRAM_DEFAULT_ONLINE_NORMAL
+ bool "Online (Normal)"
+ help
+ Automatically online the memory as ZONE_NORMAL after hotplug.
+ ZONE_NORMAL memory can be used for all allocations including
+ kernel allocations, but may not be hotremovable.
+
+ Select this for maximum memory utilization when hotremove is
+ not required.
+
+endchoice
+
config CXL_REGION_INVALIDATION_TEST
bool "CXL: Region Cache Management Bypass (TEST)"
depends on CXL_REGION
diff --git a/drivers/cxl/core/memctrl/sysram_region.c b/drivers/cxl/core/memctrl/sysram_region.c
index a7570c8a54e1..2e2d9b59a725 100644
--- a/drivers/cxl/core/memctrl/sysram_region.c
+++ b/drivers/cxl/core/memctrl/sysram_region.c
@@ -129,12 +129,69 @@ static int offline_memory_block_cb(struct memory_block *mem, void *arg)
return *rc;
}
+static int cxl_sysram_online_memory(struct range *range, int online_type)
+{
+ struct online_memory_cb_arg cb_arg = {
+ .online_type = online_type,
+ .rc = 0,
+ };
+ int rc;
+
+ rc = walk_memory_blocks(range->start, range_len(range),
+ &cb_arg, online_memory_block_cb);
+ if (!rc)
+ rc = cb_arg.rc;
+
+ return rc;
+}
+
+static int cxl_sysram_offline_memory(struct range *range)
+{
+ int offline_rc = 0;
+ int rc;
+
+ rc = walk_memory_blocks(range->start, range_len(range),
+ &offline_rc, offline_memory_block_cb);
+ if (!rc)
+ rc = offline_rc;
+
+ return rc;
+}
+
+static int cxl_sysram_auto_online(struct device *dev, struct range *range)
+{
+ int online_type;
+ int rc;
+
+ if (IS_ENABLED(CONFIG_CXL_REGION_SYSRAM_DEFAULT_OFFLINE))
+ return 0;
+
+ if (IS_ENABLED(CONFIG_CXL_REGION_SYSRAM_DEFAULT_ONLINE))
+ online_type = MMOP_ONLINE_MOVABLE;
+ else if (IS_ENABLED(CONFIG_CXL_REGION_SYSRAM_DEFAULT_ONLINE_NORMAL))
+ online_type = MMOP_ONLINE_KERNEL;
+ else
+ online_type = MMOP_ONLINE_MOVABLE;
+
+ rc = lock_device_hotplug_sysfs();
+ if (rc)
+ return rc;
+
+ rc = cxl_sysram_online_memory(range, online_type);
+
+ unlock_device_hotplug();
+
+ if (rc)
+ dev_warn(dev, "auto-online failed: %d\n", rc);
+
+ return rc;
+}
+
static ssize_t state_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct cxl_region *cxlr = to_cxl_region(dev);
- struct online_memory_cb_arg cb_arg;
struct range range;
int rc;
@@ -149,30 +206,14 @@ static ssize_t state_store(struct device *dev,
if (rc)
return rc;
- if (sysfs_streq(buf, "online")) {
- cb_arg.online_type = MMOP_ONLINE_MOVABLE;
- cb_arg.rc = 0;
- rc = walk_memory_blocks(range.start, range_len(&range),
- &cb_arg, online_memory_block_cb);
- if (!rc)
- rc = cb_arg.rc;
- } else if (sysfs_streq(buf, "online_normal")) {
- cb_arg.online_type = MMOP_ONLINE;
- cb_arg.rc = 0;
- rc = walk_memory_blocks(range.start, range_len(&range),
- &cb_arg, online_memory_block_cb);
- if (!rc)
- rc = cb_arg.rc;
- } else if (sysfs_streq(buf, "offline")) {
- int offline_rc = 0;
-
- rc = walk_memory_blocks(range.start, range_len(&range),
- &offline_rc, offline_memory_block_cb);
- if (!rc)
- rc = offline_rc;
- } else {
+ if (sysfs_streq(buf, "online"))
+ rc = cxl_sysram_online_memory(&range, MMOP_ONLINE_MOVABLE);
+ else if (sysfs_streq(buf, "online_normal"))
+ rc = cxl_sysram_online_memory(&range, MMOP_ONLINE);
+ else if (sysfs_streq(buf, "offline"))
+ rc = cxl_sysram_offline_memory(&range);
+ else
rc = -EINVAL;
- }
unlock_device_hotplug();
@@ -332,6 +373,10 @@ int devm_cxl_add_sysram_region(struct cxl_region *cxlr)
dev_dbg(dev, "%s: added %llu bytes as System RAM\n", dev_name(dev),
(unsigned long long)total_len);
+ rc = cxl_sysram_auto_online(dev, &range);
+ if (rc)
+ goto err_auto_online;
+
dev_set_drvdata(dev, data);
rc = devm_device_add_group(dev, &cxl_sysram_region_group);
if (rc)
@@ -341,6 +386,7 @@ int devm_cxl_add_sysram_region(struct cxl_region *cxlr)
err_add_group:
dev_set_drvdata(dev, NULL);
+err_auto_online:
/* if this fails, memory cannot be removed from the system until reboot */
remove_memory(range.start, range_len(&range));
err_add_memory:
--
2.52.0
Powered by blists - more mailing lists