Linux-NVME Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] nvme-multipath: expose path_state via sysfs
@ 2026-07-24  9:00 Guixin Liu
  2026-07-24  9:00 ` [PATCH v4 1/2] " Guixin Liu
  2026-07-24  9:00 ` [PATCH v4 2/2] nvme-multipath: document path_state sysfs attribute Guixin Liu
  0 siblings, 2 replies; 3+ messages in thread
From: Guixin Liu @ 2026-07-24  9:00 UTC (permalink / raw)
  To: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg,
	Nilay Shroff, Daniel Wagner, John Garry
  Cc: linux-nvme

This series adds a read-only "path_state" sysfs attribute to each NVMe
multipath path namespace device (/sys/block/nvmeXcYnZ/path_state), giving
userspace visibility into whether a path is currently usable for I/O and,
if not, the reason it is disabled.

Today users have to piece this together from the controller state and
various namespace flags. The new attribute reports the path selection
state directly, and is kept in sync with the path selection logic by
sharing a single nvme_path_get_state() helper.

Patch 1 adds the attribute and the helper; patch 2 documents it in the
stable NVMe sysfs ABI file.

Changes since v3:
- Use single-token sysfs values ("enabled", "ctrl-down", "ana-pending",
  "ns-not-ready") instead of the composite "disabled (reason)" and
  "enabled (optimized)/(non-optimized)" strings, following the sysfs
  convention of exporting one simple value per attribute.
- Drop the "enabled (optimized)" vs "enabled (non-optimized)"
  distinction; the ANA access state is already exposed through the
  existing per-path ana_state attribute.
- Add a second patch documenting path_state in the stable NVMe sysfs
  ABI (Documentation/ABI/stable/sysfs-nvme).

Changes since v2:
- Factor path disable checks into nvme_path_get_state() helper returning
  enum nvme_path_state, and rebuild nvme_path_is_disabled() on top of it
  to keep path selection logic and sysfs reporting in sync. (Nilay Shroff)
- Distinguish "enabled (optimized)" vs "enabled (non-optimized)" based on
  ANA state. (Keith Busch)

Changes since v1:
- Show specific disabled reason instead of just "disabled":
  "disabled (ctrl_down)", "disabled (ana_pending)",
  "disabled (ns_not_ready)". (Nilay Shroff)

Guixin Liu (2):
  nvme-multipath: expose path_state via sysfs
  nvme-multipath: document path_state sysfs attribute

 Documentation/ABI/stable/sysfs-nvme | 21 +++++++++++++
 drivers/nvme/host/multipath.c       | 47 +++++++++++++++++++++++++----
 drivers/nvme/host/nvme.h            |  1 +
 drivers/nvme/host/sysfs.c           |  4 ++-
 4 files changed, 66 insertions(+), 7 deletions(-)


base-commit: 7caaa4120d8dd73bb251410e1d007b4131d024c4
-- 
2.43.7



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v4 1/2] nvme-multipath: expose path_state via sysfs
  2026-07-24  9:00 [PATCH v4 0/2] nvme-multipath: expose path_state via sysfs Guixin Liu
@ 2026-07-24  9:00 ` Guixin Liu
  2026-07-24  9:00 ` [PATCH v4 2/2] nvme-multipath: document path_state sysfs attribute Guixin Liu
  1 sibling, 0 replies; 3+ messages in thread
From: Guixin Liu @ 2026-07-24  9:00 UTC (permalink / raw)
  To: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg,
	Nilay Shroff, Daniel Wagner, John Garry
  Cc: linux-nvme

Add a read-only "path_state" sysfs attribute to each NVMe path namespace
device (/sys/class/nvme/nvmeX/nvmeXcYnZ/path_state) that exposes the
current path state, including whether the path is enabled or disabled
with a specific reason.

Factor the path disable checks from nvme_path_is_disabled() into a new
nvme_path_get_state() helper that returns an enum nvme_path_state. This
keeps the path selection logic and sysfs reporting in sync, so any future
updates to the path disable criteria are automatically reflected in the
sysfs output.

Possible values:
  - "enabled"      : path is usable for I/O
  - "ctrl-down"    : controller is not live
  - "ana-pending"  : ANA state change pending
  - "ns-not-ready" : namespace is not ready

This gives userspace visibility into the multipath path selection state
without requiring users to piece together controller state and namespace
flags manually.

Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
 drivers/nvme/host/multipath.c | 47 ++++++++++++++++++++++++++++++-----
 drivers/nvme/host/nvme.h      |  1 +
 drivers/nvme/host/sysfs.c     |  4 ++-
 3 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 9b9a657fa330..84230ac02a48 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -288,7 +288,14 @@ void nvme_mpath_revalidate_paths(struct nvme_ns_head *head)
 	kblockd_schedule_work(&head->requeue_work);
 }
 
-static bool nvme_path_is_disabled(struct nvme_ns *ns)
+enum nvme_path_state {
+	NVME_PATH_ENABLED,
+	NVME_PATH_DISABLED_CTRL_DOWN,
+	NVME_PATH_DISABLED_ANA_PENDING,
+	NVME_PATH_DISABLED_NS_NOT_READY,
+};
+
+static enum nvme_path_state nvme_path_get_state(struct nvme_ns *ns)
 {
 	enum nvme_ctrl_state state = nvme_ctrl_state(ns->ctrl);
 
@@ -298,11 +305,17 @@ static bool nvme_path_is_disabled(struct nvme_ns *ns)
 	 * Otherwise it will fail immediately and return to the requeue list.
 	 */
 	if (state != NVME_CTRL_LIVE && state != NVME_CTRL_DELETING)
-		return true;
-	if (test_bit(NVME_NS_ANA_PENDING, &ns->flags) ||
-	    !test_bit(NVME_NS_READY, &ns->flags))
-		return true;
-	return false;
+		return NVME_PATH_DISABLED_CTRL_DOWN;
+	if (test_bit(NVME_NS_ANA_PENDING, &ns->flags))
+		return NVME_PATH_DISABLED_ANA_PENDING;
+	if (!test_bit(NVME_NS_READY, &ns->flags))
+		return NVME_PATH_DISABLED_NS_NOT_READY;
+	return NVME_PATH_ENABLED;
+}
+
+static bool nvme_path_is_disabled(struct nvme_ns *ns)
+{
+	return nvme_path_get_state(ns) != NVME_PATH_ENABLED;
 }
 
 static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)
@@ -1105,6 +1118,28 @@ static ssize_t queue_depth_show(struct device *dev,
 }
 DEVICE_ATTR_RO(queue_depth);
 
+static const char * const nvme_path_state_names[] = {
+	[NVME_PATH_ENABLED]			= "enabled",
+	[NVME_PATH_DISABLED_CTRL_DOWN]		= "ctrl-down",
+	[NVME_PATH_DISABLED_ANA_PENDING]	= "ana-pending",
+	[NVME_PATH_DISABLED_NS_NOT_READY]	= "ns-not-ready",
+};
+
+static ssize_t path_state_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
+	enum nvme_path_state state = nvme_path_get_state(ns);
+	const char *name = "unknown";
+
+	if (state < ARRAY_SIZE(nvme_path_state_names) &&
+	    nvme_path_state_names[state])
+		name = nvme_path_state_names[state];
+
+	return sysfs_emit(buf, "%s\n", name);
+}
+DEVICE_ATTR_RO(path_state);
+
 static ssize_t numa_nodes_show(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 824651cc898d..9a9af2a24136 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -1075,6 +1075,7 @@ extern struct device_attribute dev_attr_ana_grpid;
 extern struct device_attribute dev_attr_ana_state;
 extern struct device_attribute dev_attr_queue_depth;
 extern struct device_attribute dev_attr_numa_nodes;
+extern struct device_attribute dev_attr_path_state;
 extern struct device_attribute dev_attr_delayed_removal_secs;
 extern struct device_attribute dev_attr_multipath_failover_count;
 extern struct device_attribute dev_attr_io_requeue_no_usable_path_count;
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index 75b2d69b5957..c457a2c67c0b 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -261,6 +261,7 @@ static struct attribute *nvme_ns_attrs[] = {
 	&dev_attr_ana_state.attr,
 	&dev_attr_queue_depth.attr,
 	&dev_attr_numa_nodes.attr,
+	&dev_attr_path_state.attr,
 	&dev_attr_delayed_removal_secs.attr,
 #endif
 	&dev_attr_io_passthru_err_log_enabled.attr,
@@ -294,7 +295,8 @@ static umode_t nvme_ns_attrs_are_visible(struct kobject *kobj,
 		if (!nvme_ctrl_use_ana(nvme_get_ns_from_dev(dev)->ctrl))
 			return 0;
 	}
-	if (a == &dev_attr_queue_depth.attr || a == &dev_attr_numa_nodes.attr) {
+	if (a == &dev_attr_queue_depth.attr || a == &dev_attr_numa_nodes.attr ||
+	    a == &dev_attr_path_state.attr) {
 		if (nvme_disk_is_ns_head(dev_to_disk(dev)))
 			return 0;
 	}
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v4 2/2] nvme-multipath: document path_state sysfs attribute
  2026-07-24  9:00 [PATCH v4 0/2] nvme-multipath: expose path_state via sysfs Guixin Liu
  2026-07-24  9:00 ` [PATCH v4 1/2] " Guixin Liu
@ 2026-07-24  9:00 ` Guixin Liu
  1 sibling, 0 replies; 3+ messages in thread
From: Guixin Liu @ 2026-07-24  9:00 UTC (permalink / raw)
  To: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg,
	Nilay Shroff, Daniel Wagner, John Garry
  Cc: linux-nvme

Document the newly added /sys/block/nvmeXcYnZ/path_state attribute in
the stable NVMe sysfs ABI file, describing the possible path states and
their meaning.

Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
 Documentation/ABI/stable/sysfs-nvme | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-nvme b/Documentation/ABI/stable/sysfs-nvme
index a2f5d0710db4..04bcea5bae45 100644
--- a/Documentation/ABI/stable/sysfs-nvme
+++ b/Documentation/ABI/stable/sysfs-nvme
@@ -326,6 +326,27 @@ Description:
 		currently selected path. Returns empty if iopolicy is not
 		"numa". Requires CONFIG_NVME_MULTIPATH.
 
+What:		/sys/block/nvmeXcYnZ/path_state
+Date:		July 2026
+KernelVersion:	7.2
+Contact:	Guixin Liu <kanie@linux.alibaba.com>
+Description:
+		Shows the current multipath path state for this namespace
+		path device. Possible values:
+
+		"enabled": the path is usable for I/O.
+
+		"ctrl-down": the path is disabled because the controller
+		is not live.
+
+		"ana-pending": the path is disabled because an ANA state
+		change is pending.
+
+		"ns-not-ready": the path is disabled because the namespace
+		is not ready.
+
+		Requires CONFIG_NVME_MULTIPATH.
+
 What:		/sys/block/nvmeXnY/delayed_removal_secs
 Date:		May 2025
 KernelVersion:	6.16
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-24  9:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24  9:00 [PATCH v4 0/2] nvme-multipath: expose path_state via sysfs Guixin Liu
2026-07-24  9:00 ` [PATCH v4 1/2] " Guixin Liu
2026-07-24  9:00 ` [PATCH v4 2/2] nvme-multipath: document path_state sysfs attribute Guixin Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox