From: Dave Jiang <dave.jiang@intel.com>
To: Anisa Su <anisa.su887@gmail.com>,
linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: nvdimm@lists.linux.dev, Dan Williams <djbw@kernel.org>,
Jonathan Cameron <jic23@kernel.org>,
Davidlohr Bueso <dave@stgolabs.net>,
Ira Weiny <iweiny@kernel.org>,
Alison Schofield <alison.schofield@intel.com>,
John Groves <John@Groves.net>, Gregory Price <gourry@gourry.net>,
Anisa Su <anisa.su@samsung.com>
Subject: Re: [PATCH v6 6/7] daxctl: Add --uuid option to create-device for sparse regions
Date: Mon, 8 Jun 2026 17:12:59 -0700 [thread overview]
Message-ID: <f1bf4df1-7ff2-4e13-8632-0d0c680f3629@intel.com> (raw)
In-Reply-To: <20260523095043.471098-7-anisa.su@samsung.com>
On 5/23/26 2:50 AM, Anisa Su wrote:
> Add a --uuid option to 'daxctl create-device' that writes the given
> uuid to the new dax device's sysfs 'uuid' attribute. On sparse (DCD)
> regions this claims dax_resources whose tag matches and populates the
> seed device with their capacity; size is determined by the claim, so
> --uuid is mutually exclusive with --size.
>
> Pass "0" to claim a single untagged dax_resource. A claim that
> matches no dax_resource leaves the device at size 0; the kernel
> returns ENOENT.
>
> Plumb the write through a new daxctl_dev_set_uuid() libdaxctl helper
> (LIBDAXCTL_11) and document the option in the man page.
>
> Signed-off-by: Anisa Su <anisa.su887@gmail.com>
> ---
> Documentation/daxctl/daxctl-create-device.txt | 12 ++++
> daxctl/device.c | 72 +++++++++++++------
> daxctl/lib/libdaxctl.c | 44 ++++++++++++
> daxctl/lib/libdaxctl.sym | 5 ++
> daxctl/libdaxctl.h | 1 +
> 5 files changed, 114 insertions(+), 20 deletions(-)
>
> diff --git a/Documentation/daxctl/daxctl-create-device.txt b/Documentation/daxctl/daxctl-create-device.txt
> index b774b86..27b87d0 100644
> --- a/Documentation/daxctl/daxctl-create-device.txt
> +++ b/Documentation/daxctl/daxctl-create-device.txt
> @@ -82,6 +82,18 @@ include::region-option.txt[]
>
> The size must be a multiple of the region alignment.
>
> + Mutually exclusive with --uuid.
> +
> +--uuid=::
> + For dax devices on sparse (DCD) regions, claim dax_resource(s) whose
> + tag matches the given UUID. The device's size is determined by the
> + claimed capacity, so --uuid cannot be combined with --size.
> +
> + A non-null UUID claims every matching dax_resource in the parent
> + region. The value "0" is shorthand for the null UUID and claims a
> + single untagged dax_resource. A write that matches no dax_resource
> + fails with ENOENT and the device is left at size 0.
> +
> -a::
> --align::
> Applications that want to establish dax memory mappings with
> diff --git a/daxctl/device.c b/daxctl/device.c
> index a4e36b1..21a941e 100644
> --- a/daxctl/device.c
> +++ b/daxctl/device.c
> @@ -30,6 +30,7 @@ static struct {
> const char *size;
> const char *align;
> const char *input;
> + const char *uuid;
> bool check_config;
> bool no_online;
> bool no_movable;
> @@ -85,7 +86,9 @@ OPT_BOOLEAN('C', "check-config", ¶m.check_config, \
> #define CREATE_OPTIONS() \
> OPT_STRING('s', "size", ¶m.size, "size", "size to switch the device to"), \
> OPT_STRING('a', "align", ¶m.align, "align", "alignment to switch the device to"), \
> -OPT_STRING('\0', "input", ¶m.input, "input", "input device JSON file")
> +OPT_STRING('\0', "input", ¶m.input, "input", "input device JSON file"), \
> +OPT_STRING('\0', "uuid", ¶m.uuid, "uuid", \
> + "claim sparse dax_resource(s) matching this uuid (\"0\" for untagged)")
>
> #define DESTROY_OPTIONS() \
> OPT_BOOLEAN('f', "force", ¶m.force, \
> @@ -808,6 +811,22 @@ static int do_create(struct daxctl_region *region, long long val,
> struct daxctl_dev *dev;
> int i, rc = 0;
> long long alloc = 0;
> + uuid_t uuid;
> +
> + if (param.uuid) {
> + if (param.size) {
> + fprintf(stderr,
> + "--uuid and --size are mutually exclusive\n");
> + return -EINVAL;
> + }
> + if (strcmp(param.uuid, "0") == 0) {
> + uuid_clear(uuid);
> + } else if (uuid_parse(param.uuid, uuid) < 0) {
> + fprintf(stderr, "failed to parse uuid '%s'\n",
> + param.uuid);
> + return -EINVAL;
> + }
> + }
>
> if (daxctl_region_create_dev(region))
> return -ENOSPC;
> @@ -816,33 +835,46 @@ static int do_create(struct daxctl_region *region, long long val,
> if (!dev)
> return -ENOSPC;
>
> - if (val == -1)
> - val = daxctl_region_get_available_size(region);
> -
> - if (val <= 0)
> - return -ENOSPC;
> -
> if (align > 0) {
> rc = daxctl_dev_set_align(dev, align);
> if (rc < 0)
> return rc;
> }
>
> - /* @maps is ordered by page_offset */
> - for (i = 0; i < nmaps; i++) {
> - rc = daxctl_dev_set_mapping(dev, maps[i].start, maps[i].end);
> - if (rc < 0)
> + if (param.uuid) {
> + rc = daxctl_dev_set_uuid(dev, uuid);
> + if (rc < 0) {
> + fprintf(stderr,
> + "%s: failed to claim uuid '%s': %s\n",
> + daxctl_dev_get_devname(dev), param.uuid,
> + strerror(-rc));
> return rc;
> - alloc += (maps[i].end - maps[i].start + 1);
> - }
> -
> - if (nmaps > 0 && val > 0 && alloc != val) {
> - fprintf(stderr, "%s: allocated %lld but specified size %lld\n",
> - daxctl_dev_get_devname(dev), alloc, val);
> + }
> } else {
> - rc = daxctl_dev_set_size(dev, val);
> - if (rc < 0)
> - return rc;
> + if (val == -1)
> + val = daxctl_region_get_available_size(region);
> +
> + if (val <= 0)
> + return -ENOSPC;
> +
> + /* @maps is ordered by page_offset */
> + for (i = 0; i < nmaps; i++) {
> + rc = daxctl_dev_set_mapping(dev, maps[i].start,
> + maps[i].end);
> + if (rc < 0)
> + return rc;
> + alloc += (maps[i].end - maps[i].start + 1);
> + }
> +
> + if (nmaps > 0 && val > 0 && alloc != val) {
> + fprintf(stderr,
> + "%s: allocated %lld but specified size %lld\n",
> + daxctl_dev_get_devname(dev), alloc, val);
> + } else {
> + rc = daxctl_dev_set_size(dev, val);
> + if (rc < 0)
> + return rc;
> + }
> }
>
> rc = daxctl_dev_enable_devdax(dev);
> diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
> index 02ae7e5..fe07939 100644
> --- a/daxctl/lib/libdaxctl.c
> +++ b/daxctl/lib/libdaxctl.c
> @@ -1107,6 +1107,50 @@ DAXCTL_EXPORT int daxctl_dev_set_size(struct daxctl_dev *dev, unsigned long long
> return 0;
> }
>
> +DAXCTL_EXPORT int daxctl_dev_set_uuid(struct daxctl_dev *dev, uuid_t uuid)
> +{
> + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
> + char buf[SYSFS_ATTR_SIZE];
> + char *path = dev->dev_buf;
> + int len = dev->buf_len;
> +
> + if (snprintf(path, len, "%s/uuid", dev->dev_path) >= len) {
> + err(ctx, "%s: buffer too small!\n",
> + daxctl_dev_get_devname(dev));
> + return -ENXIO;
snprintf() returns negative errno, propogate
> + }
> +
> + if (uuid_is_null(uuid))
> + sprintf(buf, "0\n");
> + else
> + uuid_unparse(uuid, buf);
> +
> + if (sysfs_write_attr(ctx, path, buf) < 0) {
> + err(ctx, "%s: failed to set uuid\n",
> + daxctl_dev_get_devname(dev));
> + return -ENXIO;
propogate the errno from sysfs_write_attr()
> + }
> +
> + /*
> + * On a sparse region the kernel populates the device size as a
> + * side effect of claiming the matching dax_resource(s); refresh
> + * the cached size so callers see the post-claim value.
> + */
> + if (snprintf(path, len, "%s/size", dev->dev_path) >= len) {
> + err(ctx, "%s: buffer too small!\n",
> + daxctl_dev_get_devname(dev));
> + return -ENXIO;
propogate negative return value from snprintf()
> + }
> + if (sysfs_read_attr(ctx, path, buf) < 0) {
> + err(ctx, "%s: failed to read back size\n",
> + daxctl_dev_get_devname(dev));
> + return -ENXIO;
propgate negative errno from sysfs_read_attr()
> + }
> + dev->size = strtoull(buf, NULL, 0);
> +
> + return 0;
> +}
> +
> DAXCTL_EXPORT unsigned long daxctl_dev_get_align(struct daxctl_dev *dev)
> {
> return dev->align;
> diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
> index 3098811..16792eb 100644
> --- a/daxctl/lib/libdaxctl.sym
> +++ b/daxctl/lib/libdaxctl.sym
> @@ -104,3 +104,8 @@ LIBDAXCTL_10 {
> global:
> daxctl_dev_is_system_ram_capable;
> } LIBDAXCTL_9;
> +
> +LIBDAXCTL_11 {
> +global:
> + daxctl_dev_set_uuid;
> +} LIBDAXCTL_10;
> diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
> index 53c6bbd..cdd5995 100644
> --- a/daxctl/libdaxctl.h
> +++ b/daxctl/libdaxctl.h
> @@ -63,6 +63,7 @@ int daxctl_dev_get_minor(struct daxctl_dev *dev);
> unsigned long long daxctl_dev_get_resource(struct daxctl_dev *dev);
> unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev);
> int daxctl_dev_set_size(struct daxctl_dev *dev, unsigned long long size);
> +int daxctl_dev_set_uuid(struct daxctl_dev *dev, uuid_t uuid);
> unsigned long daxctl_dev_get_align(struct daxctl_dev *dev);
> int daxctl_dev_set_align(struct daxctl_dev *dev, unsigned long align);
> int daxctl_dev_set_mapping(struct daxctl_dev *dev, unsigned long long start,
next prev parent reply other threads:[~2026-06-09 0:13 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-23 9:50 [PATCH v6 0/7] ndctl: Dynamic Capacity additions for cxl-cli Anisa Su
2026-05-23 9:50 ` [PATCH v6 1/7] " Anisa Su
2026-06-08 23:18 ` Dave Jiang
2026-05-23 9:50 ` [PATCH v6 2/7] libcxl: Add Dynamic RAM A partition mode support Anisa Su
2026-06-08 23:19 ` Dave Jiang
2026-06-10 3:51 ` Richard Cheng
2026-06-10 16:55 ` Dave Jiang
2026-06-25 9:08 ` Anisa Su
2026-06-25 9:07 ` Anisa Su
2026-05-23 9:50 ` [PATCH v6 3/7] cxl/region: Add cxl-cli support for dynamic RAM A Anisa Su
2026-06-08 23:58 ` Dave Jiang
2026-05-23 9:50 ` [PATCH v6 4/7] libcxl: Add extent functionality to DC regions Anisa Su
2026-06-09 0:05 ` Dave Jiang
2026-06-25 9:18 ` Anisa Su
2026-05-23 9:50 ` [PATCH v6 5/7] cxl/region: Add extent output to region query Anisa Su
2026-06-09 0:08 ` Dave Jiang
2026-06-10 3:55 ` Richard Cheng
2026-06-16 10:47 ` Anisa Su
2026-06-16 10:45 ` Anisa Su
2026-05-23 9:50 ` [PATCH v6 6/7] daxctl: Add --uuid option to create-device for sparse regions Anisa Su
2026-06-09 0:12 ` Dave Jiang [this message]
2026-06-25 9:30 ` Anisa Su
2026-05-23 9:50 ` [PATCH v6 7/7] cxl/test: Add Dynamic Capacity tests Anisa Su
2026-06-09 0:24 ` Dave Jiang
2026-06-25 9:34 ` Anisa Su
2026-06-05 5:43 ` [PATCH v6 0/7] ndctl: Dynamic Capacity additions for cxl-cli Alison Schofield
2026-06-08 8:11 ` Anisa Su
2026-06-17 7:10 ` Alison Schofield
2026-06-18 5:52 ` Anisa Su
2026-06-19 0:38 ` Alison Schofield
2026-06-24 4:51 ` 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=f1bf4df1-7ff2-4e13-8632-0d0c680f3629@intel.com \
--to=dave.jiang@intel.com \
--cc=John@Groves.net \
--cc=alison.schofield@intel.com \
--cc=anisa.su887@gmail.com \
--cc=anisa.su@samsung.com \
--cc=dave@stgolabs.net \
--cc=djbw@kernel.org \
--cc=gourry@gourry.net \
--cc=iweiny@kernel.org \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nvdimm@lists.linux.dev \
/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
Powered by JetHome