From: Anisa Su <anisa.su887@gmail.com>
To: linux-cxl@vger.kernel.org
Cc: nvdimm@lists.linux.dev, linux-kernel@vger.kernel.org,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Jonathan Cameron <jic23@kernel.org>,
Davidlohr Bueso <dave@stgolabs.net>,
Ira Weiny <iweiny@kernel.org>,
Vishal Verma <vishal.l.verma@intel.com>,
Fan Ni <nifan.cxl@gmail.com>, Li Ming <ming.li@zohomail.com>,
Benjamin Cheatham <benjamin.cheatham@amd.com>,
Gregory Price <gourry@gourry.net>,
Richard Cheng <icheng@nvidia.com>,
Anisa Su <anisa.su@samsung.com>
Subject: [PATCH v1 02/14] cxl/port: Add dynamic capacity options to endpoint decoder mode
Date: Thu, 5 Nov 2026 08:02:26 +0900 [thread overview]
Message-ID: <20261104230445.66625-3-anisa.su@samsung.com> (raw)
In-Reply-To: <20261104230445.66625-1-anisa.su@samsung.com>
Endpoints can now carry a dynamic ram partition following the
persistent memory partition. A DC partition is further described by
two properties reported in its CDAT DSMAS entry: shareable and
read-only.
Expand the decoder mode to accept 'dynamic_ram', 'dynamic_ram_shared',
'dynamic_ram_ro' and 'dynamic_ram_shared_ro'. cxl_dpa_set_part()
selects the first dynamic ram partition whose properties match exactly.
DCD may be disabled during validation after the DC partition(s) were
added to the DPA layout, so a decoder may only be assigned to a DC
partition while DCD is enabled for its memdev. Add a helper,
cxled_dcd_enabled(), to check cxl_dcd_supported().
Signed-off-by: Anisa Su <anisa.su@samsung.com>
Tested-by: Wonjae Lee <wj28.lee@samsung.com>
Tested-by: Junhee Park <jh9934.park@samsung.com>
Tested-by: Heesoo Kim <habil.kim@samsung.com>
---
Documentation/ABI/testing/sysfs-bus-cxl | 25 +++++++----
drivers/cxl/core/core.h | 23 ++++++++++-
drivers/cxl/core/hdm.c | 21 ++++++++--
drivers/cxl/core/port.c | 55 ++++++++++++++++++++++---
4 files changed, 105 insertions(+), 19 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl
index 7352dbd70bc7..bcbc44fea6db 100644
--- a/Documentation/ABI/testing/sysfs-bus-cxl
+++ b/Documentation/ABI/testing/sysfs-bus-cxl
@@ -339,22 +339,29 @@ Description:
What: /sys/bus/cxl/devices/decoderX.Y/mode
-Date: May, 2022
-KernelVersion: v6.0
+Date: May, 2022, November, 2026
+KernelVersion: v6.0, v7.5 (dynamic_ram)
Contact: linux-cxl@vger.kernel.org
Description:
(RW) When a CXL decoder is of devtype "cxl_decoder_endpoint" it
translates from a host physical address range, to a device
local address range. Device-local address ranges are further
- split into a 'ram' (volatile memory) range and 'pmem'
- (persistent memory) range. The 'mode' attribute emits one of
- 'ram', 'pmem', or 'none'. The 'none' indicates the decoder is
- not actively decoding, or no DPA allocation policy has been
- set.
+ split into a 'ram' (volatile memory) range, 'pmem' (persistent
+ memory) range, and dynamic capacity ranges. The 'mode'
+ attribute emits one of 'ram', 'pmem', 'none', or a dynamic
+ capacity selector: 'dynamic_ram', 'dynamic_ram_shared',
+ 'dynamic_ram_ro' or 'dynamic_ram_shared_ro', composed from the
+ shareable and read-only properties of the partition the decoder
+ points at. The 'none' indicates the decoder is not actively
+ decoding, or no DPA allocation policy has been set.
'mode' can be written, when the decoder is in the 'disabled'
- state, with either 'ram' or 'pmem' to set the boundaries for the
- next allocation.
+ state, with 'ram', 'pmem', or one of the dynamic capacity
+ selectors to set the boundaries for the next allocation. A
+ selector picks the first dynamic capacity partition whose
+ shareable and read-only properties match it exactly, and is
+ accepted only while the driver has dynamic capacity enabled
+ for the device.
What: /sys/bus/cxl/devices/decoderX.Y/dpa_resource
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 8a81be004d00..24fbb5718abc 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -6,6 +6,7 @@
#include <cxl/mailbox.h>
#include <linux/rwsem.h>
+#include <cxlmem.h>
extern const struct device_type cxl_nvdimm_bridge_type;
extern const struct device_type cxl_nvdimm_type;
@@ -18,6 +19,25 @@ enum cxl_detach_mode {
DETACH_INVALIDATE,
};
+static inline struct cxl_memdev_state *
+cxled_to_mds(struct cxl_endpoint_decoder *cxled)
+{
+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+
+ return to_cxl_memdev_state(cxlmd->cxlds);
+}
+
+/* Type-2 devices have no memdev state; nothing else leaves @cxlds NULL here */
+static inline bool cxled_dcd_enabled(struct cxl_endpoint_decoder *cxled)
+{
+ struct cxl_memdev_state *mds = cxled_to_mds(cxled);
+
+ return mds && cxl_dcd_supported(mds);
+}
+
+const char *cxl_dc_mode_name(bool shareable, bool read_only);
+int cxl_dc_mode_parse(const char *buf, bool *shareable, bool *read_only);
+
#ifdef CONFIG_CXL_REGION
struct cxl_region_context {
@@ -104,7 +124,8 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
struct dentry *cxl_debugfs_create_dir(const char *dir);
int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
- enum cxl_partition_mode mode);
+ enum cxl_partition_mode mode, bool shareable,
+ bool read_only);
struct cxl_memdev_state;
int cxl_mem_get_partition_info(struct cxl_memdev_state *mds);
int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size);
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index fdcef20e01ba..36fba4cff493 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -619,8 +619,14 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
return 0;
}
+/*
+ * Select the first partition of @mode. For dynamic capacity the shareable
+ * and read-only flags must match exactly as well, so each selector names
+ * one kind of partition.
+ */
int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
- enum cxl_partition_mode mode)
+ enum cxl_partition_mode mode, bool shareable,
+ bool read_only)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
@@ -631,9 +637,16 @@ int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE)
return -EBUSY;
- for (part = 0; part < cxlds->nr_partitions; part++)
- if (cxlds->part[part].mode == mode)
- break;
+ for (part = 0; part < cxlds->nr_partitions; part++) {
+ struct cxl_dpa_partition *p = &cxlds->part[part];
+
+ if (p->mode != mode)
+ continue;
+ if (mode == CXL_PARTMODE_DYNAMIC_RAM &&
+ (p->shareable != shareable || p->read_only != read_only))
+ continue;
+ break;
+ }
if (part >= cxlds->nr_partitions) {
dev_dbg(dev, "unsupported mode: %d\n", mode);
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index f3705ea44db7..9b71b58d4e36 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -203,6 +203,40 @@ static ssize_t target_list_show(struct device *dev,
}
static DEVICE_ATTR_RO(target_list);
+/* Dynamic capacity selectors: the flags name one kind of DC partition */
+static const struct {
+ const char *name;
+ bool shareable;
+ bool read_only;
+} cxl_dc_modes[] = {
+ { "dynamic_ram", false, false },
+ { "dynamic_ram_shared", true, false },
+ { "dynamic_ram_ro", false, true },
+ { "dynamic_ram_shared_ro", true, true },
+};
+
+const char *cxl_dc_mode_name(bool shareable, bool read_only)
+{
+ for (int i = 0; i < ARRAY_SIZE(cxl_dc_modes); i++)
+ if (cxl_dc_modes[i].shareable == shareable &&
+ cxl_dc_modes[i].read_only == read_only)
+ return cxl_dc_modes[i].name;
+ return "";
+}
+
+/* Map a dynamic_ram selector to its partition flags; -EINVAL if unknown */
+int cxl_dc_mode_parse(const char *buf, bool *shareable, bool *read_only)
+{
+ for (int i = 0; i < ARRAY_SIZE(cxl_dc_modes); i++) {
+ if (!sysfs_streq(buf, cxl_dc_modes[i].name))
+ continue;
+ *shareable = cxl_dc_modes[i].shareable;
+ *read_only = cxl_dc_modes[i].read_only;
+ return 0;
+ }
+ return -EINVAL;
+}
+
static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -215,6 +249,9 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
if (part < 0)
desc = "none";
+ else if (cxlds->part[part].mode == CXL_PARTMODE_DYNAMIC_RAM)
+ desc = cxl_dc_mode_name(cxlds->part[part].shareable,
+ cxlds->part[part].read_only);
else
desc = cxlds->part[part].res.name;
@@ -225,17 +262,25 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
+ bool shareable = false, read_only = false;
enum cxl_partition_mode mode;
ssize_t rc;
- if (sysfs_streq(buf, "pmem"))
+ if (sysfs_streq(buf, "pmem")) {
mode = CXL_PARTMODE_PMEM;
- else if (sysfs_streq(buf, "ram"))
+ } else if (sysfs_streq(buf, "ram")) {
mode = CXL_PARTMODE_RAM;
- else
- return -EINVAL;
+ } else {
+ if (cxl_dc_mode_parse(buf, &shareable, &read_only))
+ return -EINVAL;
+ mode = CXL_PARTMODE_DYNAMIC_RAM;
+ }
+
+ /* The DC partition may outlive DCD support; refuse it when disabled */
+ if (mode == CXL_PARTMODE_DYNAMIC_RAM && !cxled_dcd_enabled(cxled))
+ return -ENXIO;
- rc = cxl_dpa_set_part(cxled, mode);
+ rc = cxl_dpa_set_part(cxled, mode, shareable, read_only);
if (rc)
return rc;
--
2.43.0
next prev parent reply other threads:[~2026-11-04 23:02 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 23:02 [PATCH v1 00/14] DCD CXL Series: Dynamic Capacity extent handling Anisa Su
2026-11-04 23:02 ` [PATCH v1 01/14] cxl/core: Return endpoint decoder information from region search Anisa Su
2026-11-04 23:02 ` Anisa Su [this message]
2026-11-04 23:02 ` [PATCH v1 03/14] cxl/region: Add dynamic DAX region support Anisa Su
2026-11-04 23:02 ` [PATCH v1 04/14] cxl/mem: Introduce DC event handlers Anisa Su
2026-11-04 23:02 ` [PATCH v1 05/14] cxl/mem: Add 20 second timeout for stalled DC event chains Anisa Su
2026-11-04 23:02 ` [PATCH v1 06/14] cxl/extent: Handle DC Add Capacity events Anisa Su
2026-11-04 23:02 ` [PATCH v1 07/14] cxl/mem: Drop misaligned DCD extent groups Anisa Su
2026-11-04 23:02 ` [PATCH v1 08/14] cxl/extent: Validate DC extent partition Anisa Su
2026-11-04 23:02 ` [PATCH v1 09/14] cxl/mem: Enforce tag-group semantics Anisa Su
2026-11-04 23:02 ` [PATCH v1 10/14] cxl/extent: Enforce cross-region tag uniqueness Anisa Su
2026-11-04 23:02 ` [PATCH v1 11/14] cxl/extent: Handle DC Release Capacity events Anisa Su
2026-11-04 23:02 ` [PATCH v1 12/14] cxl/region: Read existing extents on region creation Anisa Su
2026-11-04 23:02 ` [PATCH v1 13/14] cxl/mem: Trace Dynamic capacity Event Record Anisa Su
2026-11-04 23:02 ` [PATCH v1 14/14] Documentation/cxl: Document DCD extent handling Anisa Su
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104230445.66625-3-anisa.su@samsung.com \
--to=anisa.su887@gmail.com \
--cc=alison.schofield@intel.com \
--cc=anisa.su@samsung.com \
--cc=benjamin.cheatham@amd.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=gourry@gourry.net \
--cc=icheng@nvidia.com \
--cc=iweiny@kernel.org \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=nifan.cxl@gmail.com \
--cc=nvdimm@lists.linux.dev \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®