Linux CXL
 help / color / mirror / Atom feed
From: Davidlohr Bueso <dave@stgolabs.net>
To: vishal.l.verma@intel.com
Cc: dan.j.williams@intel.com, dave.jiang@intel.com,
	fan.ni@samsung.com, a.manzanares@samsung.com, dave@stgolabs.net,
	linux-cxl@vger.kernel.org
Subject: [PATCH 1/2] cxl/memdev: Introduce wait-sanitize functionality
Date: Thu, 13 Jul 2023 12:54:50 -0700	[thread overview]
Message-ID: <20230713195455.19769-2-dave@stgolabs.net> (raw)
In-Reply-To: <20230713195455.19769-1-dave@stgolabs.net>

Add a new cxl_memdev_wait_sanitize() to libcxl to support
waiting for sanitize operation to be done in the background,
if any.

This is analogous to 'ndctl wait-overwrite'.

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
 Documentation/cxl/cxl-wait-sanitize.txt | 35 +++++++++++
 Documentation/cxl/lib/libcxl.txt        |  1 +
 Documentation/cxl/meson.build           |  1 +
 cxl/builtin.h                           |  1 +
 cxl/cxl.c                               |  1 +
 cxl/lib/libcxl.c                        | 78 +++++++++++++++++++++++++
 cxl/lib/libcxl.sym                      |  5 ++
 cxl/libcxl.h                            |  1 +
 cxl/memdev.c                            | 26 +++++++++
 9 files changed, 149 insertions(+)
 create mode 100644 Documentation/cxl/cxl-wait-sanitize.txt

diff --git a/Documentation/cxl/cxl-wait-sanitize.txt b/Documentation/cxl/cxl-wait-sanitize.txt
new file mode 100644
index 000000000000..365b11597afd
--- /dev/null
+++ b/Documentation/cxl/cxl-wait-sanitize.txt
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+
+cxl-wait-sanitize(1)
+====================
+
+NAME
+----
+cxl-wait-sanitize - wait for a sanitization operation to complete
+
+SYNOPSIS
+--------
+[verse]
+'cxl wait-sanitize' <mem0> [<mem1>..<memN>] [<options>]
+
+DESCRIPTION
+-----------
+The kernel provides a POLL(2) capable sysfs file ('security/state') to
+indicate the state of device sanitization. When sanitization is in progress,
+this command waits for a change in the state of this file across all
+specified memdevs.
+
+OPTIONS
+-------
+<memdev>::
+include::memdev-option.txt[]
+
+-b::
+--bus=::
+include::bus-option.txt[]
+
+-v::
+--verbose::
+	Emit debug messages.
+
+include::../copyright.txt[]
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
index 31bc85511270..3ea816bde471 100644
--- a/Documentation/cxl/lib/libcxl.txt
+++ b/Documentation/cxl/lib/libcxl.txt
@@ -135,6 +135,7 @@ int cxl_memdev_write_label(struct cxl_memdev *memdev, void *buf, size_t length,
 struct cxl_cmd *cxl_cmd_new_get_partition(struct cxl_memdev *memdev);
 struct cxl_cmd *cxl_cmd_new_set_partition(struct cxl_memdev *memdev,
 					  unsigned long long volatile_size);
+int cxl_memdev_wait_sanitize(struct cxl_memdev *memdev);
 
 ----
 
diff --git a/Documentation/cxl/meson.build b/Documentation/cxl/meson.build
index a6d77ab8cbc2..ebf214ae30df 100644
--- a/Documentation/cxl/meson.build
+++ b/Documentation/cxl/meson.build
@@ -45,6 +45,7 @@ cxl_manpages = [
   'cxl-disable-region.txt',
   'cxl-enable-region.txt',
   'cxl-destroy-region.txt',
+  'cxl-wait-sanitize.txt',
   'cxl-monitor.txt',
 ]
 
diff --git a/cxl/builtin.h b/cxl/builtin.h
index 9baa43b8a2ac..04f613703eac 100644
--- a/cxl/builtin.h
+++ b/cxl/builtin.h
@@ -22,6 +22,7 @@ int cmd_create_region(int argc, const char **argv, struct cxl_ctx *ctx);
 int cmd_enable_region(int argc, const char **argv, struct cxl_ctx *ctx);
 int cmd_disable_region(int argc, const char **argv, struct cxl_ctx *ctx);
 int cmd_destroy_region(int argc, const char **argv, struct cxl_ctx *ctx);
+int cmd_wait_sanitize(int argc, const char **argv, struct cxl_ctx *ctx);
 #ifdef ENABLE_LIBTRACEFS
 int cmd_monitor(int argc, const char **argv, struct cxl_ctx *ctx);
 #else
diff --git a/cxl/cxl.c b/cxl/cxl.c
index 3be7026f43d3..bf55e8bcb2f7 100644
--- a/cxl/cxl.c
+++ b/cxl/cxl.c
@@ -76,6 +76,7 @@ static struct cmd_struct commands[] = {
 	{ "enable-region", .c_fn = cmd_enable_region },
 	{ "disable-region", .c_fn = cmd_disable_region },
 	{ "destroy-region", .c_fn = cmd_destroy_region },
+	{ "wait-sanitize", .c_fn = cmd_wait_sanitize },
 	{ "monitor", .c_fn = cmd_monitor },
 };
 
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 769cd8a75de9..172dfb47a2dd 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <dirent.h>
 #include <unistd.h>
+#include <poll.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -3968,6 +3969,83 @@ CXL_EXPORT struct cxl_cmd *cxl_cmd_new_set_partition(struct cxl_memdev *memdev,
 	return cmd;
 }
 
+CXL_EXPORT int cxl_memdev_wait_sanitize(struct cxl_memdev *memdev)
+{
+	struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
+	struct pollfd fds;
+	char buf[SYSFS_ATTR_SIZE];
+	int fd = 0, rc;
+	char *path = memdev->dev_buf;
+	int len = memdev->buf_len;
+
+	if (snprintf(path, len,
+		     "%s/security/state", memdev->dev_path) >= len) {
+		err(ctx, "%s: buffer too small!\n",
+		    cxl_memdev_get_devname(memdev));
+		return -ERANGE;
+	}
+
+	fd = open(path, O_RDONLY|O_CLOEXEC);
+	if (fd < 0) {
+		rc = -errno;
+		err(ctx, "open: %s\n", strerror(errno));
+		return rc;
+	}
+	memset(&fds, 0, sizeof(fds));
+	fds.fd = fd;
+
+	rc = sysfs_read_attr(ctx, path, buf);
+	if (rc < 0) {
+		rc = -EOPNOTSUPP;
+		goto out;
+	}
+	/* skipping if we aren't in sanitize state */
+	if (strncmp(buf, "sanitize", 8) != 0) {
+		rc = 0;
+		goto out;
+	}
+
+	for (;;) {
+		rc = sysfs_read_attr(ctx, path, buf);
+		if (rc < 0) {
+			rc = -EOPNOTSUPP;
+			break;
+		}
+
+		if (strncmp(buf, "sanitize", 8) == 0) {
+			rc = poll(&fds, 1, -1);
+			if (rc < 0) {
+				rc = -errno;
+				err(ctx, "poll error: %s\n", strerror(errno));
+				break;
+			}
+			dbg(ctx, "poll wake: revents: %d\n", fds.revents);
+			if (pread(fd, buf, 1, 0) == -1) {
+				rc = -errno;
+				break;
+			}
+			fds.revents = 0;
+		} else {
+			if (strncmp(buf, "disabled", 8) == 0)
+				rc = 1;
+			break;
+		}
+	}
+
+	if (rc == 1)
+		dbg(ctx, "%s: sanitize complete\n",
+		    cxl_memdev_get_devname(memdev));
+	else if (rc == 0)
+		dbg(ctx, "%s: sanitize skipped\n",
+		    cxl_memdev_get_devname(memdev));
+	else
+		dbg(ctx, "%s: sanitize error waiting for complete\n",
+		    cxl_memdev_get_devname(memdev));
+ out:
+	close(fd);
+	return rc;
+}
+
 CXL_EXPORT int cxl_cmd_submit(struct cxl_cmd *cmd)
 {
 	struct cxl_memdev *memdev = cmd->memdev;
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index c6545c717d50..efc7c1090a5c 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -250,3 +250,8 @@ global:
 	cxl_region_get_daxctl_region;
 	cxl_port_get_parent_dport;
 } LIBCXL_4;
+
+LIBCXL_6 {
+global:
+	cxl_memdev_wait_sanitize;
+} LIBCXL_5;
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 0218d730298f..c1656cb77103 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -416,6 +416,7 @@ unsigned long long cxl_cmd_partition_get_next_volatile_size(struct cxl_cmd *cmd)
 unsigned long long cxl_cmd_partition_get_next_persistent_size(struct cxl_cmd *cmd);
 struct cxl_cmd *cxl_cmd_new_set_partition(struct cxl_memdev *memdev,
 		unsigned long long volatile_size);
+int cxl_memdev_wait_sanitize(struct cxl_memdev *memdev);
 
 enum cxl_setpartition_mode {
 	CXL_SETPART_NEXTBOOT,
diff --git a/cxl/memdev.c b/cxl/memdev.c
index 0b3ad0223bec..3134a6f6ab27 100644
--- a/cxl/memdev.c
+++ b/cxl/memdev.c
@@ -135,6 +135,11 @@ static const struct option free_dpa_options[] = {
 	OPT_END(),
 };
 
+static const struct option wait_sanitize_options[] = {
+	BASE_OPTIONS(),
+	OPT_END(),
+};
+
 enum reserve_dpa_mode {
 	DPA_ALLOC,
 	DPA_FREE,
@@ -653,6 +658,16 @@ out_err:
 	return rc;
 }
 
+static int action_wait_sanitize(struct cxl_memdev *memdev,
+				struct action_context *actx)
+{
+	/*
+	 * It's perfectly ok for the device to be active
+	 * or enabled, so no need to check anything here.
+	 */
+	return cxl_memdev_wait_sanitize(memdev);
+}
+
 static int memdev_action(int argc, const char **argv, struct cxl_ctx *ctx,
 			 int (*action)(struct cxl_memdev *memdev,
 				       struct action_context *actx),
@@ -893,3 +908,14 @@ int cmd_free_dpa(int argc, const char **argv, struct cxl_ctx *ctx)
 
 	return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_wait_sanitize(int argc, const char **argv, struct cxl_ctx *ctx)
+{
+	int count = memdev_action(argc, argv, ctx, action_wait_sanitize,
+		wait_sanitize_options,
+		"cxl wait-sanitize <mem0> [<mem1>..<memn>] [<options>]");
+	log_info(&ml, "sanitization completed on %d mem device%s\n",
+		 count >= 0 ? count : 0, count > 1 ? "s" : "");
+
+	return count >= 0 ? 0 : EXIT_FAILURE;
+}
-- 
2.41.0


  reply	other threads:[~2023-07-13 20:31 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-13 19:54 [PATCH -ndctl v2 0/2] cxl: Support memdev sanitation Davidlohr Bueso
2023-07-13 19:54 ` Davidlohr Bueso [this message]
2023-07-13 19:54 ` [PATCH 2/2] cxl/memdev: Introduce sanitize-memdev functionality Davidlohr Bueso
2023-07-14  3:24   ` Alison Schofield
2023-07-14 15:00     ` Davidlohr Bueso
2023-07-14 18:35       ` Alison Schofield
2023-07-24 21:38         ` Verma, Vishal L
  -- strict thread matches above, loose matches on Subject: below --
2023-04-23  1:59 [PATCH -ndctl 0/2] cxl: Support memdev sanitation Davidlohr Bueso
2023-04-23  1:59 ` [PATCH 1/2] cxl/memdev: Introduce wait-sanitize functionality Davidlohr Bueso
2023-04-26 18:19   ` Verma, Vishal L
2023-04-26 18:25     ` Davidlohr Bueso
2023-04-26 22:01       ` Verma, Vishal L

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=20230713195455.19769-2-dave@stgolabs.net \
    --to=dave@stgolabs.net \
    --cc=a.manzanares@samsung.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=fan.ni@samsung.com \
    --cc=linux-cxl@vger.kernel.org \
    --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