From: Ira Weiny <ira.weiny@intel.com>
To: Alison Schofield <alison.schofield@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>,
Jonathan Cameron <jonathan.cameron@Huawei.com>,
Fan Ni <fan.ni@samsung.com>,
Sushant1 Kumar <sushant1.kumar@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev,
Ira Weiny <ira.weiny@intel.com>
Subject: [ndctl PATCH v4 6/9] cxl/region: Add cxl-cli support for DCD regions
Date: Sat, 14 Dec 2024 20:58:33 -0600 [thread overview]
Message-ID: <20241214-dcd-region2-v4-6-36550a97f8e2@intel.com> (raw)
In-Reply-To: <20241214-dcd-region2-v4-0-36550a97f8e2@intel.com>
CXL Dynamic Capacity Devices (DCDs) optionally support dynamic capacity
with up to eight partitions (Regions) (dc0-dc7). CXL regions can now be
sparse and defined as dynamic capacity (dc).
DCD region creation requires a specific partition, or decoder mode, to
be supplied. Introduce a required option for dc regions to specify the
decoder mode.
Add support for dynamic capacity region creation.
Based on an original patch from Navneet Singh.
Signed-off-by: Sushant1 Kumar <sushant1.kumar@intel.com>
Co-developed-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
Documentation/cxl/cxl-create-region.txt | 11 ++++++++--
cxl/json.c | 27 ++++++++++++++++++++++-
cxl/memdev.c | 4 +++-
cxl/region.c | 39 ++++++++++++++++++++++++++++++++-
4 files changed, 76 insertions(+), 5 deletions(-)
diff --git a/Documentation/cxl/cxl-create-region.txt b/Documentation/cxl/cxl-create-region.txt
index b244af60b8a63281ed63d0d6f4027ea729ad51b0..a12cc8d3f19fa582376599ecc8512640f15ce42c 100644
--- a/Documentation/cxl/cxl-create-region.txt
+++ b/Documentation/cxl/cxl-create-region.txt
@@ -75,8 +75,9 @@ include::bus-option.txt[]
-t::
--type=::
- Specify the region type - 'pmem' or 'ram'. Default to root decoder
- capability, and if that is ambiguous, default to 'pmem'.
+ Specify the region type - 'pmem', 'ram', or 'dc'. Default to root
+ decoder capability including the first of any DC partition found. If
+ the decoder capability is ambiguous, default to 'pmem'.
-U::
--uuid=::
@@ -105,6 +106,12 @@ include::bus-option.txt[]
supplied, the first cross-host bridge (if available), decoder that
supports the largest interleave will be chosen.
+-M::
+--decoder-mode=::
+ For a 'dc' region type, specify the dynamic capacity partition to be
+ used on each device, 'dcX' [where X is 0-7]. Ignored for region type
+ of 'ram' or 'pmem'.
+
-Q::
--enforce-qos::
Parameter to enforce qos_class mismatch failure. Region create operation
diff --git a/cxl/json.c b/cxl/json.c
index dcd3cc28393faf7e8adf299a857531ecdeaac50a..c5391be84fba51da57fc15ece7c1f94cce139276 100644
--- a/cxl/json.c
+++ b/cxl/json.c
@@ -754,12 +754,15 @@ err_free:
return jpoison;
}
+#define DC_SIZE_NAME_LEN 64
struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev,
unsigned long flags)
{
const char *devname = cxl_memdev_get_devname(memdev);
+ char size_name[DC_SIZE_NAME_LEN];
struct json_object *jdev, *jobj;
unsigned long long serial, size;
+ enum cxl_decoder_mode mode;
const char *fw_version;
int numa_node;
int qos_class;
@@ -800,6 +803,16 @@ struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev,
}
}
+ for (mode = CXL_DECODER_MODE_DC0; mode <= CXL_DECODER_MODE_DC7; mode++) {
+ size = cxl_memdev_get_dc_size(memdev, mode);
+ if (!size)
+ continue;
+ jobj = util_json_object_size(size, flags);
+ if (!jobj)
+ continue;
+ sprintf(size_name, "%s_size", cxl_decoder_mode_name(mode));
+ json_object_object_add(jdev, size_name, jobj);
+ }
if (flags & UTIL_JSON_HEALTH) {
jobj = util_cxl_memdev_health_to_json(memdev, flags);
if (jobj)
@@ -948,12 +961,15 @@ struct json_object *util_cxl_bus_to_json(struct cxl_bus *bus,
return jbus;
}
+#define DC_CAPABILITY_NAME_LEN 16
struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
unsigned long flags)
{
const char *devname = cxl_decoder_get_devname(decoder);
struct cxl_port *port = cxl_decoder_get_port(decoder);
+ char dc_capable_name[DC_CAPABILITY_NAME_LEN];
struct json_object *jdecoder, *jobj;
+ enum cxl_decoder_mode mode;
struct cxl_region *region;
u64 val, size;
@@ -1013,7 +1029,7 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
}
if (cxl_port_is_endpoint(port)) {
- enum cxl_decoder_mode mode = cxl_decoder_get_mode(decoder);
+ mode = cxl_decoder_get_mode(decoder);
size = cxl_decoder_get_dpa_size(decoder);
val = cxl_decoder_get_dpa_resource(decoder);
@@ -1059,6 +1075,15 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
json_object_object_add(
jdecoder, "volatile_capable", jobj);
}
+ for (mode = CXL_DECODER_MODE_DC0; mode <= CXL_DECODER_MODE_DC7; mode++) {
+ if (!cxl_decoder_is_dc_capable(decoder, mode))
+ continue;
+ jobj = json_object_new_boolean(true);
+ if (!jobj)
+ continue;
+ sprintf(dc_capable_name, "%s_capable", cxl_decoder_mode_name(mode));
+ json_object_object_add(jdecoder, dc_capable_name, jobj);
+ }
}
if (cxl_port_is_root(port) &&
diff --git a/cxl/memdev.c b/cxl/memdev.c
index 6e44d1578d03b6af998502e54714635b8f31b556..b132527d7c21e99c9da75ea7cbf1497fd924a142 100644
--- a/cxl/memdev.c
+++ b/cxl/memdev.c
@@ -269,8 +269,10 @@ static int __reserve_dpa(struct cxl_memdev *memdev,
if (mode == CXL_DECODER_MODE_RAM)
avail_dpa = cxl_memdev_get_ram_size(memdev);
- else
+ else if (mode == CXL_DECODER_MODE_PMEM)
avail_dpa = cxl_memdev_get_pmem_size(memdev);
+ else if (cxl_decoder_mode_is_dc(mode))
+ avail_dpa = cxl_memdev_get_dc_size(memdev, mode);
cxl_decoder_foreach(port, decoder) {
size = cxl_decoder_get_dpa_size(decoder);
diff --git a/cxl/region.c b/cxl/region.c
index 527bd6708b162815068a95ddb360fce3914347de..79f434b0c99545523f3b8209f90ff2f02111881c 100644
--- a/cxl/region.c
+++ b/cxl/region.c
@@ -26,6 +26,7 @@ static struct region_params {
const char *uuid;
const char *root_decoder;
const char *region;
+ const char *decoder_mode;
int ways;
int granularity;
bool memdevs;
@@ -79,9 +80,11 @@ OPT_INTEGER('w', "ways", ¶m.ways, \
OPT_INTEGER('g', "granularity", ¶m.granularity, \
"granularity of the interleave set"), \
OPT_STRING('t', "type", ¶m.type, \
- "region type", "region type - 'pmem' or 'ram'"), \
+ "region type", "region type - 'pmem', 'ram', or 'dc'"), \
OPT_STRING('U', "uuid", ¶m.uuid, \
"region uuid", "uuid for the new region (default: autogenerate)"), \
+OPT_STRING('M', "decoder-mode", ¶m.decoder_mode, "decoder mode", \
+ "decoder mode for dc regions - 'dcX' [where X is 0-7]"), \
OPT_BOOLEAN('m', "memdevs", ¶m.memdevs, \
"non-option arguments are memdevs"), \
OPT_BOOLEAN('u', "human", ¶m.human, "use human friendly number formats"), \
@@ -314,12 +317,19 @@ static int parse_create_options(struct cxl_ctx *ctx, int count,
log_err(&rl, "unsupported type: %s\n", param.type);
goto err;
}
+ if (p->region_mode == CXL_REGION_MODE_DC && !param.decoder_mode) {
+ log_err(&rl, "dc type requires a decoder mode\n");
+ goto err;
+ }
}
switch (p->region_mode) {
case CXL_REGION_MODE_RAM:
p->decoder_mode = CXL_DECODER_MODE_RAM;
break;
+ case CXL_REGION_MODE_DC:
+ p->decoder_mode = cxl_decoder_mode_from_ident(param.decoder_mode);
+ break;
case CXL_REGION_MODE_PMEM:
default:
p->decoder_mode = CXL_DECODER_MODE_PMEM;
@@ -427,6 +437,9 @@ static void collect_minsize(struct cxl_ctx *ctx, struct parsed_params *p)
case CXL_DECODER_MODE_PMEM:
size = cxl_memdev_get_pmem_size(memdev);
break;
+ case CXL_DECODER_MODE_DC0 ... CXL_DECODER_MODE_DC7:
+ size = cxl_memdev_get_dc_size(memdev, p->decoder_mode);
+ break;
default:
/* Shouldn't ever get here */ ;
}
@@ -498,6 +511,13 @@ static int validate_decoder(struct cxl_decoder *decoder,
return -EINVAL;
}
break;
+ case CXL_DECODER_MODE_DC0 ... CXL_DECODER_MODE_DC7:
+ if (!cxl_decoder_is_dc_capable(decoder, p->decoder_mode)) {
+ log_err(&rl, "%s is not %s capable\n", devname,
+ cxl_decoder_mode_name(p->decoder_mode));
+ return -EINVAL;
+ }
+ break;
default:
log_err(&rl, "unknown type: %s\n", param.type);
return -EINVAL;
@@ -514,10 +534,20 @@ static int validate_decoder(struct cxl_decoder *decoder,
static void set_type_from_decoder(struct cxl_ctx *ctx, struct parsed_params *p)
{
+ enum cxl_decoder_mode mode;
+
/* if param.type was explicitly specified, nothing to do here */
if (param.type)
return;
+ for (mode = CXL_DECODER_MODE_DC0; mode <= CXL_DECODER_MODE_DC7; mode++) {
+ if (cxl_decoder_is_dc_capable(p->root_decoder, mode)) {
+ p->decoder_mode = mode;
+ p->region_mode = CXL_REGION_MODE_DC;
+ break;
+ }
+ }
+
/*
* default to pmem if both types are set, otherwise the single
* capability dominates.
@@ -713,6 +743,13 @@ static int create_region(struct cxl_ctx *ctx, int *count,
param.root_decoder);
return -ENXIO;
}
+ } else if (p->region_mode == CXL_REGION_MODE_DC) {
+ region = cxl_decoder_create_dc_region(p->root_decoder);
+ if (!region) {
+ log_err(&rl, "failed to create region under %s\n",
+ param.root_decoder);
+ return -ENXIO;
+ }
} else {
log_err(&rl, "region type '%s' is not supported\n",
param.type);
--
2.47.1
next prev parent reply other threads:[~2024-12-15 2:58 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-15 2:58 [ndctl PATCH v4 0/9] ndctl: Dynamic Capacity additions for cxl-cli Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 1/9] ndctl/cxl-events: Don't fail test until event counts are reported Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 2/9] ndctl/cxl/region: Report max size for region creation Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 3/9] libcxl: Separate region mode from decoder mode Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 4/9] cxl/region: Use new region mode in cxl-cli Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 5/9] libcxl: Add Dynamic Capacity region support Ira Weiny
2025-02-11 3:12 ` Alison Schofield
2024-12-15 2:58 ` Ira Weiny [this message]
2025-02-11 3:21 ` [ndctl PATCH v4 6/9] cxl/region: Add cxl-cli support for DCD regions Alison Schofield
2024-12-15 2:58 ` [ndctl PATCH v4 7/9] libcxl: Add extent functionality to DC regions Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 8/9] cxl/region: Add extent output to region query Ira Weiny
2025-02-11 3:24 ` Alison Schofield
2025-02-12 22:03 ` Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 9/9] cxl/test: Add Dynamic Capacity tests Ira Weiny
2025-02-11 3:33 ` Alison Schofield
2025-02-11 2:47 ` [ndctl PATCH v4 0/9] ndctl: Dynamic Capacity additions for cxl-cli Alison Schofield
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=20241214-dcd-region2-v4-6-36550a97f8e2@intel.com \
--to=ira.weiny@intel.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=fan.ni@samsung.com \
--cc=jonathan.cameron@Huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nvdimm@lists.linux.dev \
--cc=sushant1.kumar@intel.com \
--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