anitazha / rpms / ndctl

Forked from rpms/ndctl 2 years ago
Clone
Jeff Moyer 2c91dc
From e2d5cbab4a4b530b679172ae7ca59cc506d1d4cc Mon Sep 17 00:00:00 2001
Jeff Moyer 2c91dc
From: Alison Schofield <alison.schofield@intel.com>
Jeff Moyer 2c91dc
Date: Tue, 22 Feb 2022 11:56:08 -0800
Jeff Moyer 2c91dc
Subject: [PATCH 137/217] cxl: add command 'cxl set-partition'
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
CXL devices may support both volatile and persistent memory capacity.
Jeff Moyer 2c91dc
The amount of device capacity set aside for each type is typically
Jeff Moyer 2c91dc
established at the factory, but some devices also allow for dynamic
Jeff Moyer 2c91dc
re-partitioning. Add a command for this purpose.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
 usage: cxl set-partition <mem0> [<mem1>..<memN>] [<options>]
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
    -v, --verbose         turn on debug
Jeff Moyer 2c91dc
    -S, --serial          use serial numbers to id memdevs
Jeff Moyer 2c91dc
    -t, --type <type>     'pmem' or 'volatile' (Default: 'pmem')
Jeff Moyer 2c91dc
    -s, --size <size>     size in bytes (Default: all available capacity)
Jeff Moyer 2c91dc
    -a, --align           auto-align --size per device's requirement
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Link: https://lore.kernel.org/r/e7accc7ba93def81b48304cf5fb483345757410d.1645558189.git.alison.schofield@intel.com
Jeff Moyer 2c91dc
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
---
Jeff Moyer 2c91dc
 Documentation/cxl/cxl-set-partition.txt |  68 ++++++++
Jeff Moyer 2c91dc
 Documentation/cxl/meson.build           |   1 +
Jeff Moyer 2c91dc
 cxl/builtin.h                           |   1 +
Jeff Moyer 2c91dc
 cxl/cxl.c                               |   1 +
Jeff Moyer 2c91dc
 cxl/memdev.c                            | 206 ++++++++++++++++++++++++
Jeff Moyer 2c91dc
 5 files changed, 277 insertions(+)
Jeff Moyer 2c91dc
 create mode 100644 Documentation/cxl/cxl-set-partition.txt
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
diff --git a/Documentation/cxl/cxl-set-partition.txt b/Documentation/cxl/cxl-set-partition.txt
Jeff Moyer 2c91dc
new file mode 100644
Jeff Moyer 2c91dc
index 0000000..1e548af
Jeff Moyer 2c91dc
--- /dev/null
Jeff Moyer 2c91dc
+++ b/Documentation/cxl/cxl-set-partition.txt
Jeff Moyer 2c91dc
@@ -0,0 +1,68 @@
Jeff Moyer 2c91dc
+// SPDX-License-Identifier: GPL-2.0
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+cxl-set-partition(1)
Jeff Moyer 2c91dc
+====================
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+NAME
Jeff Moyer 2c91dc
+----
Jeff Moyer 2c91dc
+cxl-set-partition - set the partitioning between volatile and persistent capacity on a CXL memdev
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+SYNOPSIS
Jeff Moyer 2c91dc
+--------
Jeff Moyer 2c91dc
+[verse]
Jeff Moyer 2c91dc
+'cxl set-partition <mem0> [ [<mem1>..<memN>] [<options>]'
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+DESCRIPTION
Jeff Moyer 2c91dc
+-----------
Jeff Moyer 2c91dc
+CXL devices may support both volatile and persistent memory capacity.
Jeff Moyer 2c91dc
+The amount of device capacity set aside for each type is typically
Jeff Moyer 2c91dc
+established at the factory, but some devices also allow for dynamic
Jeff Moyer 2c91dc
+re-partitioning.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+Use this command to partition a device into volatile and persistent
Jeff Moyer 2c91dc
+capacity. The change in partitioning becomes the “next” configuration,
Jeff Moyer 2c91dc
+to become active on the next device reset.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+Use "cxl list -m <memdev> -I" to examine the partitioning capabilities
Jeff Moyer 2c91dc
+of a device. A partition_alignment_size value of zero means there is
Jeff Moyer 2c91dc
+no available capacity and therefore the partitions cannot be changed.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+Using this command to change the size of the persistent capacity shall
Jeff Moyer 2c91dc
+result in the loss of data stored.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+OPTIONS
Jeff Moyer 2c91dc
+-------
Jeff Moyer 2c91dc
+<memory device(s)>::
Jeff Moyer 2c91dc
+include::memdev-option.txt[]
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+-t::
Jeff Moyer 2c91dc
+--type=::
Jeff Moyer 2c91dc
+	Type of partition, 'pmem' or 'volatile', to modify.
Jeff Moyer 2c91dc
+	Default: 'pmem'
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+-s::
Jeff Moyer 2c91dc
+--size=::
Jeff Moyer 2c91dc
+	Size of the <type> partition in bytes. Size must align to the
Jeff Moyer 2c91dc
+	devices alignment requirement. Use 'cxl list -m <memdev> -I'
Jeff Moyer 2c91dc
+	to find 'partition_alignment_size', or, use the --align option.
Jeff Moyer 2c91dc
+	Default: All available capacity is assigned to <type>.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+-a::
Jeff Moyer 2c91dc
+--align::
Jeff Moyer 2c91dc
+	Select this option to allow the automatic alignment of --size
Jeff Moyer 2c91dc
+	to meet device alignment requirements. When using this option,
Jeff Moyer 2c91dc
+	specify the minimum --size of the --type partition needed. When
Jeff Moyer 2c91dc
+	this option is omitted, the command fails if --size is not
Jeff Moyer 2c91dc
+	properly aligned. Use 'cxl list -m <memdev> -I' to examine the
Jeff Moyer 2c91dc
+	partition_alignment_size.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+-v::
Jeff Moyer 2c91dc
+        Turn on verbose debug messages in the library (if libcxl was built with
Jeff Moyer 2c91dc
+        logging and debug enabled).
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+include::../copyright.txt[]
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+SEE ALSO
Jeff Moyer 2c91dc
+--------
Jeff Moyer 2c91dc
+linkcxl:cxl-list[1],
Jeff Moyer 2c91dc
+CXL-2.0 8.2.9.5.2
Jeff Moyer 2c91dc
diff --git a/Documentation/cxl/meson.build b/Documentation/cxl/meson.build
Jeff Moyer 2c91dc
index 96f4666..e927644 100644
Jeff Moyer 2c91dc
--- a/Documentation/cxl/meson.build
Jeff Moyer 2c91dc
+++ b/Documentation/cxl/meson.build
Jeff Moyer 2c91dc
@@ -34,6 +34,7 @@ cxl_manpages = [
Jeff Moyer 2c91dc
   'cxl-disable-memdev.txt',
Jeff Moyer 2c91dc
   'cxl-enable-port.txt',
Jeff Moyer 2c91dc
   'cxl-disable-port.txt',
Jeff Moyer 2c91dc
+  'cxl-set-partition.txt',
Jeff Moyer 2c91dc
 ]
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 foreach man : cxl_manpages
Jeff Moyer 2c91dc
diff --git a/cxl/builtin.h b/cxl/builtin.h
Jeff Moyer 2c91dc
index 3123d5e..7bbad98 100644
Jeff Moyer 2c91dc
--- a/cxl/builtin.h
Jeff Moyer 2c91dc
+++ b/cxl/builtin.h
Jeff Moyer 2c91dc
@@ -14,4 +14,5 @@ int cmd_disable_memdev(int argc, const char **argv, struct cxl_ctx *ctx);
Jeff Moyer 2c91dc
 int cmd_enable_memdev(int argc, const char **argv, struct cxl_ctx *ctx);
Jeff Moyer 2c91dc
 int cmd_disable_port(int argc, const char **argv, struct cxl_ctx *ctx);
Jeff Moyer 2c91dc
 int cmd_enable_port(int argc, const char **argv, struct cxl_ctx *ctx);
Jeff Moyer 2c91dc
+int cmd_set_partition(int argc, const char **argv, struct cxl_ctx *ctx);
Jeff Moyer 2c91dc
 #endif /* _CXL_BUILTIN_H_ */
Jeff Moyer 2c91dc
diff --git a/cxl/cxl.c b/cxl/cxl.c
Jeff Moyer 2c91dc
index c20c569..ab4bbec 100644
Jeff Moyer 2c91dc
--- a/cxl/cxl.c
Jeff Moyer 2c91dc
+++ b/cxl/cxl.c
Jeff Moyer 2c91dc
@@ -68,6 +68,7 @@ static struct cmd_struct commands[] = {
Jeff Moyer 2c91dc
 	{ "enable-memdev", .c_fn = cmd_enable_memdev },
Jeff Moyer 2c91dc
 	{ "disable-port", .c_fn = cmd_disable_port },
Jeff Moyer 2c91dc
 	{ "enable-port", .c_fn = cmd_enable_port },
Jeff Moyer 2c91dc
+	{ "set-partition", .c_fn = cmd_set_partition },
Jeff Moyer 2c91dc
 };
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 int main(int argc, const char **argv)
Jeff Moyer 2c91dc
diff --git a/cxl/memdev.c b/cxl/memdev.c
Jeff Moyer 2c91dc
index 90b33e1..91d914d 100644
Jeff Moyer 2c91dc
--- a/cxl/memdev.c
Jeff Moyer 2c91dc
+++ b/cxl/memdev.c
Jeff Moyer 2c91dc
@@ -6,11 +6,14 @@
Jeff Moyer 2c91dc
 #include <unistd.h>
Jeff Moyer 2c91dc
 #include <limits.h>
Jeff Moyer 2c91dc
 #include <util/log.h>
Jeff Moyer 2c91dc
+#include <util/json.h>
Jeff Moyer 2c91dc
+#include <util/size.h>
Jeff Moyer 2c91dc
 #include <cxl/libcxl.h>
Jeff Moyer 2c91dc
 #include <util/parse-options.h>
Jeff Moyer 2c91dc
 #include <ccan/minmax/minmax.h>
Jeff Moyer 2c91dc
 #include <ccan/array_size/array_size.h>
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+#include "json.h"
Jeff Moyer 2c91dc
 #include "filter.h"
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 struct action_context {
Jeff Moyer 2c91dc
@@ -26,10 +29,18 @@ static struct parameters {
Jeff Moyer 2c91dc
 	bool verbose;
Jeff Moyer 2c91dc
 	bool serial;
Jeff Moyer 2c91dc
 	bool force;
Jeff Moyer 2c91dc
+	bool align;
Jeff Moyer 2c91dc
+	const char *type;
Jeff Moyer 2c91dc
+	const char *size;
Jeff Moyer 2c91dc
 } param;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 static struct log_ctx ml;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+enum cxl_setpart_type {
Jeff Moyer 2c91dc
+	CXL_SETPART_PMEM,
Jeff Moyer 2c91dc
+	CXL_SETPART_VOLATILE,
Jeff Moyer 2c91dc
+};
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 #define BASE_OPTIONS() \
Jeff Moyer 2c91dc
 OPT_BOOLEAN('v',"verbose", &param.verbose, "turn on debug"), \
Jeff Moyer 2c91dc
 OPT_BOOLEAN('S', "serial", &param.serial, "use serial numbers to id memdevs")
Jeff Moyer 2c91dc
@@ -51,6 +62,14 @@ OPT_UINTEGER('O', "offset", &param.offset, \
Jeff Moyer 2c91dc
 OPT_BOOLEAN('f', "force", &param.force,                                \
Jeff Moyer 2c91dc
 	    "DANGEROUS: override active memdev safety checks")
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+#define SET_PARTITION_OPTIONS() \
Jeff Moyer 2c91dc
+OPT_STRING('t', "type",  &param.type, "type",			\
Jeff Moyer 2c91dc
+	"'pmem' or 'volatile' (Default: 'pmem')"),		\
Jeff Moyer 2c91dc
+OPT_STRING('s', "size",  &param.size, "size",			\
Jeff Moyer 2c91dc
+	"size in bytes (Default: all available capacity)"),	\
Jeff Moyer 2c91dc
+OPT_BOOLEAN('a', "align",  &param.align,			\
Jeff Moyer 2c91dc
+	"auto-align --size per device's requirement")
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 static const struct option read_options[] = {
Jeff Moyer 2c91dc
 	BASE_OPTIONS(),
Jeff Moyer 2c91dc
 	LABEL_OPTIONS(),
Jeff Moyer 2c91dc
@@ -82,6 +101,12 @@ static const struct option enable_options[] = {
Jeff Moyer 2c91dc
 	OPT_END(),
Jeff Moyer 2c91dc
 };
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+static const struct option set_partition_options[] = {
Jeff Moyer 2c91dc
+	BASE_OPTIONS(),
Jeff Moyer 2c91dc
+	SET_PARTITION_OPTIONS(),
Jeff Moyer 2c91dc
+	OPT_END(),
Jeff Moyer 2c91dc
+};
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 static int action_disable(struct cxl_memdev *memdev, struct action_context *actx)
Jeff Moyer 2c91dc
 {
Jeff Moyer 2c91dc
 	if (!cxl_memdev_is_enabled(memdev))
Jeff Moyer 2c91dc
@@ -209,6 +234,176 @@ out:
Jeff Moyer 2c91dc
 	return rc;
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+static unsigned long long
Jeff Moyer 2c91dc
+partition_align(const char *devname, enum cxl_setpart_type type,
Jeff Moyer 2c91dc
+		unsigned long long volatile_size, unsigned long long alignment,
Jeff Moyer 2c91dc
+		unsigned long long available)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	if (IS_ALIGNED(volatile_size, alignment))
Jeff Moyer 2c91dc
+		return volatile_size;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	if (!param.align) {
Jeff Moyer 2c91dc
+		log_err(&ml, "%s: size %lld is not partition aligned %lld\n",
Jeff Moyer 2c91dc
+			devname, volatile_size, alignment);
Jeff Moyer 2c91dc
+		return ULLONG_MAX;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/* Align based on partition type to fulfill users size request */
Jeff Moyer 2c91dc
+	if (type == CXL_SETPART_PMEM)
Jeff Moyer 2c91dc
+		volatile_size = ALIGN_DOWN(volatile_size, alignment);
Jeff Moyer 2c91dc
+	else
Jeff Moyer 2c91dc
+		volatile_size = ALIGN(volatile_size, alignment);
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/* Fail if the align pushes size over the available limit. */
Jeff Moyer 2c91dc
+	if (volatile_size > available) {
Jeff Moyer 2c91dc
+		log_err(&ml, "%s: aligned partition size %lld exceeds available size %lld\n",
Jeff Moyer 2c91dc
+			devname, volatile_size, available);
Jeff Moyer 2c91dc
+		volatile_size = ULLONG_MAX;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	return volatile_size;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+static unsigned long long
Jeff Moyer 2c91dc
+param_size_to_volatile_size(const char *devname, enum cxl_setpart_type type,
Jeff Moyer 2c91dc
+		unsigned long long size, unsigned long long available)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	/* User omits size option. Apply all available capacity to type. */
Jeff Moyer 2c91dc
+	if (size == ULLONG_MAX) {
Jeff Moyer 2c91dc
+		if (type == CXL_SETPART_PMEM)
Jeff Moyer 2c91dc
+			return 0;
Jeff Moyer 2c91dc
+		return available;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/* User includes a size option. Apply it to type */
Jeff Moyer 2c91dc
+	if (size > available) {
Jeff Moyer 2c91dc
+		log_err(&ml, "%s: %lld exceeds available capacity %lld\n",
Jeff Moyer 2c91dc
+			devname, size, available);
Jeff Moyer 2c91dc
+			return ULLONG_MAX;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+	if (type == CXL_SETPART_PMEM)
Jeff Moyer 2c91dc
+		return available - size;
Jeff Moyer 2c91dc
+	return size;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+/*
Jeff Moyer 2c91dc
+ * Return the volatile_size to use in the CXL set paritition
Jeff Moyer 2c91dc
+ * command, or ULLONG_MAX if unable to validate the partition
Jeff Moyer 2c91dc
+ * request.
Jeff Moyer 2c91dc
+ */
Jeff Moyer 2c91dc
+static unsigned long long
Jeff Moyer 2c91dc
+validate_partition(struct cxl_memdev *memdev, enum cxl_setpart_type type,
Jeff Moyer 2c91dc
+		unsigned long long size)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	unsigned long long total_cap, volatile_only, persistent_only;
Jeff Moyer 2c91dc
+	const char *devname = cxl_memdev_get_devname(memdev);
Jeff Moyer 2c91dc
+	unsigned long long volatile_size = ULLONG_MAX;
Jeff Moyer 2c91dc
+	unsigned long long available, alignment;
Jeff Moyer 2c91dc
+	struct cxl_cmd *cmd;
Jeff Moyer 2c91dc
+	int rc;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	cmd = cxl_cmd_new_identify(memdev);
Jeff Moyer 2c91dc
+	if (!cmd)
Jeff Moyer 2c91dc
+		return ULLONG_MAX;
Jeff Moyer 2c91dc
+	rc = cxl_cmd_submit(cmd);
Jeff Moyer 2c91dc
+	if (rc < 0)
Jeff Moyer 2c91dc
+		goto out;
Jeff Moyer 2c91dc
+	rc = cxl_cmd_get_mbox_status(cmd);
Jeff Moyer 2c91dc
+	if (rc != 0)
Jeff Moyer 2c91dc
+		goto out;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	alignment = cxl_cmd_identify_get_partition_align(cmd);
Jeff Moyer 2c91dc
+	if (alignment == 0) {
Jeff Moyer 2c91dc
+		log_err(&ml, "%s: no available capacity\n", devname);
Jeff Moyer 2c91dc
+		goto out;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/* Calculate the actual available capacity */
Jeff Moyer 2c91dc
+	total_cap = cxl_cmd_identify_get_total_size(cmd);
Jeff Moyer 2c91dc
+	volatile_only = cxl_cmd_identify_get_volatile_only_size(cmd);
Jeff Moyer 2c91dc
+	persistent_only = cxl_cmd_identify_get_persistent_only_size(cmd);
Jeff Moyer 2c91dc
+	available = total_cap - volatile_only - persistent_only;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/* Translate the users size request into an aligned volatile_size */
Jeff Moyer 2c91dc
+	volatile_size = param_size_to_volatile_size(devname, type, size,
Jeff Moyer 2c91dc
+				available);
Jeff Moyer 2c91dc
+	if (volatile_size == ULLONG_MAX)
Jeff Moyer 2c91dc
+		goto out;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	volatile_size = partition_align(devname, type, volatile_size, alignment,
Jeff Moyer 2c91dc
+				available);
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+out:
Jeff Moyer 2c91dc
+	cxl_cmd_unref(cmd);
Jeff Moyer 2c91dc
+	return volatile_size;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+static int action_setpartition(struct cxl_memdev *memdev,
Jeff Moyer 2c91dc
+		struct action_context *actx)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	const char *devname = cxl_memdev_get_devname(memdev);
Jeff Moyer 2c91dc
+	enum cxl_setpart_type type = CXL_SETPART_PMEM;
Jeff Moyer 2c91dc
+	unsigned long long size = ULLONG_MAX;
Jeff Moyer 2c91dc
+	struct json_object *jmemdev;
Jeff Moyer 2c91dc
+	struct cxl_cmd *cmd;
Jeff Moyer 2c91dc
+	int rc;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	if (param.type) {
Jeff Moyer 2c91dc
+		if (strcmp(param.type, "pmem") == 0)
Jeff Moyer 2c91dc
+			/* default */;
Jeff Moyer 2c91dc
+		else if (strcmp(param.type, "volatile") == 0)
Jeff Moyer 2c91dc
+			type = CXL_SETPART_VOLATILE;
Jeff Moyer 2c91dc
+		else {
Jeff Moyer 2c91dc
+			log_err(&ml, "invalid type '%s'\n", param.type);
Jeff Moyer 2c91dc
+			return -EINVAL;
Jeff Moyer 2c91dc
+		}
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	if (param.size) {
Jeff Moyer 2c91dc
+		size = parse_size64(param.size);
Jeff Moyer 2c91dc
+		if (size == ULLONG_MAX) {
Jeff Moyer 2c91dc
+			log_err(&ml, "%s: failed to parse size option '%s'\n",
Jeff Moyer 2c91dc
+			devname, param.size);
Jeff Moyer 2c91dc
+			return -EINVAL;
Jeff Moyer 2c91dc
+		}
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	size = validate_partition(memdev, type, size);
Jeff Moyer 2c91dc
+	if (size == ULLONG_MAX)
Jeff Moyer 2c91dc
+		return -EINVAL;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	cmd = cxl_cmd_new_set_partition(memdev, size);
Jeff Moyer 2c91dc
+	if (!cmd) {
Jeff Moyer 2c91dc
+		rc = -ENXIO;
Jeff Moyer 2c91dc
+		goto out_err;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	rc = cxl_cmd_submit(cmd);
Jeff Moyer 2c91dc
+	if (rc < 0) {
Jeff Moyer 2c91dc
+		log_err(&ml, "cmd submission failed: %s\n", strerror(-rc));
Jeff Moyer 2c91dc
+		goto out_cmd;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	rc = cxl_cmd_get_mbox_status(cmd);
Jeff Moyer 2c91dc
+	if (rc != 0) {
Jeff Moyer 2c91dc
+		log_err(&ml, "%s: mbox status: %d\n", __func__, rc);
Jeff Moyer 2c91dc
+		rc = -ENXIO;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+out_cmd:
Jeff Moyer 2c91dc
+	cxl_cmd_unref(cmd);
Jeff Moyer 2c91dc
+out_err:
Jeff Moyer 2c91dc
+	if (rc)
Jeff Moyer 2c91dc
+		log_err(&ml, "%s error: %s\n", devname, strerror(-rc));
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	jmemdev = util_cxl_memdev_to_json(memdev, UTIL_JSON_PARTITION);
Jeff Moyer 2c91dc
+	if (jmemdev)
Jeff Moyer 2c91dc
+		printf("%s\n", json_object_to_json_string_ext(jmemdev,
Jeff Moyer 2c91dc
+		       JSON_C_TO_STRING_PRETTY));
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	return rc;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 static int memdev_action(int argc, const char **argv, struct cxl_ctx *ctx,
Jeff Moyer 2c91dc
 			 int (*action)(struct cxl_memdev *memdev,
Jeff Moyer 2c91dc
 				       struct action_context *actx),
Jeff Moyer 2c91dc
@@ -398,3 +593,14 @@ int cmd_enable_memdev(int argc, const char **argv, struct cxl_ctx *ctx)
Jeff Moyer 2c91dc
 		 count > 1 ? "s" : "");
Jeff Moyer 2c91dc
 	return count >= 0 ? 0 : EXIT_FAILURE;
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+int cmd_set_partition(int argc, const char **argv, struct cxl_ctx *ctx)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	int count = memdev_action(argc, argv, ctx, action_setpartition,
Jeff Moyer 2c91dc
+			set_partition_options,
Jeff Moyer 2c91dc
+			"cxl set-partition <mem0> [<mem1>..<memN>] [<options>]");
Jeff Moyer 2c91dc
+	log_info(&ml, "set_partition %d mem%s\n", count >= 0 ? count : 0,
Jeff Moyer 2c91dc
+		 count > 1 ? "s" : "");
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	return count >= 0 ? 0 : EXIT_FAILURE;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
-- 
Jeff Moyer 2c91dc
2.27.0
Jeff Moyer 2c91dc