From: 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>,
Navneet Singh <navneet.singh@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>,
Sushant1 Kumar <sushant1.kumar@intel.com>
Subject: [ndctl PATCH v3 6/9] cxl/region: Add cxl-cli support for DCD regions
Date: Fri, 15 Nov 2024 12:46:24 -0600 [thread overview]
Message-ID: <20241115-dcd-region2-v3-6-585d480ccdab@intel.com> (raw)
In-Reply-To: <20241115-dcd-region2-v3-0-585d480ccdab@intel.com>
From: Navneet Singh <navneet.singh@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.
Signed-off-by: Navneet Singh <navneet.singh@intel.com>
Co-developed-by: Sushant1 Kumar <sushant1.kumar@intel.com>
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>
---
Changes:
[djiang: remove errant white space changes]
[djiang: use for loop for dc capability sets]
[djiang/iweiny: change cxl_memdev_get_dc_size() to take mode]
[djiang/iweiny: change cxl_decoder_is_dc_capable() to take mode]
[Alison: s/Co-Authored-by/Co-developed-by/]
[Alison: document new libcxl calls]
[Alison: reduce indentation]
[Alison: Fix libcxl export symbols]
[iweiny: Add get mode documentation]
[iweiny: add docs for DC support]
[iweiny: Add -M option to clarify region vs decoder mode]
---
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.0
next prev parent reply other threads:[~2024-11-15 18:46 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-15 18:46 [ndctl PATCH v3 0/9] ndctl: Dynamic Capacity additions for cxl-cli Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 1/9] ndctl/cxl-events: Don't fail test until event counts are reported Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 2/9] ndctl/cxl/region: Report max size for region creation Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 3/9] libcxl: Separate region mode from decoder mode Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 4/9] cxl/region: Use new region mode in cxl-cli Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 5/9] libcxl: Add Dynamic Capacity region support ira.weiny
2024-11-15 18:46 ` ira.weiny [this message]
2024-11-15 18:46 ` [ndctl PATCH v3 7/9] libcxl: Add extent functionality to DC regions Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 8/9] cxl/region: Add extent output to region query Ira Weiny
2024-11-15 18:46 ` [ndctl PATCH v3 9/9] cxl/test: Add Dynamic Capacity tests Ira Weiny
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=20241115-dcd-region2-v3-6-585d480ccdab@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=navneet.singh@intel.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.