Linux-NVME Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state
@ 2026-07-07 12:11 Guixin Liu
  2026-07-07 12:11 ` [PATCH v2 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Guixin Liu @ 2026-07-07 12:11 UTC (permalink / raw)
  To: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Hannes Reinecke, Daniel Wagner, Shin'ichiro Kawasaki
  Cc: linux-nvme, xlpang, oliver.yang

This series adds debugfs support for inspecting NVMe target reservation
(PR) state at the namespace level.

Patch 1 introduces per-namespace debugfs directories under each subsystem,
providing the infrastructure for namespace-specific debug entries.

Patch 2 adds a 'reservation' file that exposes the persistent reservation
state including enable status, generation counter, notification mask,
holder information, and the full registrant list.

Example output with two registered hosts and an active holder:

  $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
  enable=1
  generation=2
  notify_mask=reg_preempted,resv_released,resv_preempted
  rtype=write_exclusive
  holder=11111111-1111-1111-1111-111111111111,0x1111
  reg=11111111-1111-1111-1111-111111111111,0x1111
  reg=22222222-2222-2222-2222-222222222222,0x2222

v1->v2:
  - Switch the output to a "key=value" line format so it is easier to
    parse from scripts (Daniel Wagner).
  - Emit the registrant list as repeated "reg=" lines instead of a
    "registrants:" header with indented entries.
  - Print the holder as "holder=<uuid>,0x<rkey>" and report an empty
    holder/rtype as "none".
  - Stringify notify_mask as a comma-separated list of masked
    notification names (reg_preempted, resv_released, resv_preempted)
    instead of a raw hex bitmask; empty mask is reported as "none".
  - When reservation is not enabled, print only "enable=0".

Guixin Liu (2):
  nvmet: add namespace-level debugfs directory
  nvmet: expose reservation state through debugfs

 drivers/nvme/target/core.c    |   2 +
 drivers/nvme/target/debugfs.c | 103 ++++++++++++++++++++++++++++++++++
 drivers/nvme/target/debugfs.h |   5 ++
 drivers/nvme/target/nvmet.h   |   3 +
 4 files changed, 113 insertions(+)

-- 
2.43.7



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

* [PATCH v2 1/2] nvmet: add namespace-level debugfs directory
  2026-07-07 12:11 [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
@ 2026-07-07 12:11 ` Guixin Liu
  2026-07-07 12:11 ` [PATCH v2 2/2] nvmet: expose reservation state through debugfs Guixin Liu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Guixin Liu @ 2026-07-07 12:11 UTC (permalink / raw)
  To: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Hannes Reinecke, Daniel Wagner, Shin'ichiro Kawasaki
  Cc: linux-nvme, xlpang, oliver.yang

Add per-namespace debugfs directory support under the subsystem debugfs
directory. Each enabled namespace gets a ns<nsid>/ directory created
during nvmet_ns_enable() and removed during nvmet_ns_disable().

This provides the infrastructure for exposing namespace-specific debug
information in subsequent patches.

Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
 drivers/nvme/target/core.c    |  2 ++
 drivers/nvme/target/debugfs.c | 21 +++++++++++++++++++++
 drivers/nvme/target/debugfs.h |  5 +++++
 drivers/nvme/target/nvmet.h   |  3 +++
 4 files changed, 31 insertions(+)

diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 62dd59b9aa4f..9752913e05c6 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -616,6 +616,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
 	nvmet_ns_changed(subsys, ns->nsid);
 	ns->enabled = true;
 	xa_set_mark(&subsys->namespaces, ns->nsid, NVMET_NS_ENABLED);
+	nvmet_debugfs_ns_setup(ns);
 	ret = 0;
 out_unlock:
 	mutex_unlock(&subsys->lock);
@@ -642,6 +643,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
 
 	ns->enabled = false;
 	xa_clear_mark(&subsys->namespaces, ns->nsid, NVMET_NS_ENABLED);
+	nvmet_debugfs_ns_free(ns);
 
 	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
 		pci_dev_put(radix_tree_delete(&ctrl->p2p_ns_map, ns->nsid));
diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index 5dcbd5aa86e1..e6f51eb59010 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -153,6 +153,27 @@ static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
 NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
 #endif
 
+void nvmet_debugfs_ns_setup(struct nvmet_ns *ns)
+{
+	char name[16];
+	struct dentry *parent = ns->subsys->debugfs_dir;
+
+	if (!parent)
+		return;
+	snprintf(name, sizeof(name), "ns%u", ns->nsid);
+	ns->debugfs_dir = debugfs_create_dir(name, parent);
+	if (IS_ERR(ns->debugfs_dir)) {
+		ns->debugfs_dir = NULL;
+		return;
+	}
+}
+
+void nvmet_debugfs_ns_free(struct nvmet_ns *ns)
+{
+	debugfs_remove_recursive(ns->debugfs_dir);
+	ns->debugfs_dir = NULL;
+}
+
 int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
 {
 	char name[32];
diff --git a/drivers/nvme/target/debugfs.h b/drivers/nvme/target/debugfs.h
index cfb8bbf6a297..b559d254fc2a 100644
--- a/drivers/nvme/target/debugfs.h
+++ b/drivers/nvme/target/debugfs.h
@@ -14,6 +14,8 @@ int nvmet_debugfs_subsys_setup(struct nvmet_subsys *subsys);
 void nvmet_debugfs_subsys_free(struct nvmet_subsys *subsys);
 int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl);
 void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl);
+void nvmet_debugfs_ns_setup(struct nvmet_ns *ns);
+void nvmet_debugfs_ns_free(struct nvmet_ns *ns);
 
 int __init nvmet_init_debugfs(void);
 void nvmet_exit_debugfs(void);
@@ -30,6 +32,9 @@ static inline int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
 }
 static inline void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl) {}
 
+static inline void nvmet_debugfs_ns_setup(struct nvmet_ns *ns) {}
+static inline void nvmet_debugfs_ns_free(struct nvmet_ns *ns) {}
+
 static inline int __init nvmet_init_debugfs(void)
 {
     return 0;
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 3305a88684ec..142a78d9160f 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -128,6 +128,9 @@ struct nvmet_ns {
 	u8			csi;
 	struct nvmet_pr		pr;
 	struct xarray		pr_per_ctrl_refs;
+#ifdef CONFIG_NVME_TARGET_DEBUGFS
+	struct dentry		*debugfs_dir;
+#endif
 };
 
 static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)
-- 
2.43.7



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

* [PATCH v2 2/2] nvmet: expose reservation state through debugfs
  2026-07-07 12:11 [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
  2026-07-07 12:11 ` [PATCH v2 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
@ 2026-07-07 12:11 ` Guixin Liu
  2026-07-09  5:57 ` [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Christoph Hellwig
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Guixin Liu @ 2026-07-07 12:11 UTC (permalink / raw)
  To: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Hannes Reinecke, Daniel Wagner, Shin'ichiro Kawasaki
  Cc: linux-nvme, xlpang, oliver.yang

Add a 'reservation' debugfs file under each namespace directory that
shows the persistent reservation state, including enable status,
generation counter, notify mask, current holder info, and the full
registrant list with hostid and reservation key.

Each attribute is emitted as a single "key=value" line so the output is
easy to parse from scripts. The registrant list is emitted as repeated
"reg=" lines. The notify mask is emitted as a comma-separated list of
masked notification names. Empty values are reported as "none". Example
output:

    enable=1
    generation=2
    notify_mask=reg_preempted,resv_released,resv_preempted
    rtype=write_exclusive
    holder=11111111-1111-1111-1111-111111111111,0x1111
    reg=11111111-1111-1111-1111-111111111111,0x1111
    reg=22222222-2222-2222-2222-222222222222,0x2222

When reservation is not enabled only "enable=0" is printed.

The output uses rcu_read_lock() for safe access to the holder and
registrant_list, consistent with other PR read paths.

Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
 drivers/nvme/target/debugfs.c | 82 +++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index e6f51eb59010..e85fe1d4c9f8 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -153,6 +153,86 @@ static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
 NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
 #endif
 
+static const char *const nvmet_pr_type_names[] = {
+	[NVME_PR_WRITE_EXCLUSIVE]		= "write_exclusive",
+	[NVME_PR_EXCLUSIVE_ACCESS]		= "exclusive_access",
+	[NVME_PR_WRITE_EXCLUSIVE_REG_ONLY]	= "write_exclusive_reg_only",
+	[NVME_PR_EXCLUSIVE_ACCESS_REG_ONLY]	= "exclusive_access_reg_only",
+	[NVME_PR_WRITE_EXCLUSIVE_ALL_REGS]	= "write_exclusive_all_regs",
+	[NVME_PR_EXCLUSIVE_ACCESS_ALL_REGS]	= "exclusive_access_all_regs",
+};
+
+static const char *nvmet_pr_type_to_str(enum nvme_pr_type type)
+{
+	if (type < ARRAY_SIZE(nvmet_pr_type_names) &&
+	    nvmet_pr_type_names[type])
+		return nvmet_pr_type_names[type];
+	return "unknown";
+}
+
+static const char *const nvmet_pr_notify_names[] = {
+	[NVME_PR_NOTIFY_BIT_REG_PREEMPTED]	= "reg_preempted",
+	[NVME_PR_NOTIFY_BIT_RESV_RELEASED]	= "resv_released",
+	[NVME_PR_NOTIFY_BIT_RESV_PREEMPTED]	= "resv_preempted",
+};
+
+static void nvmet_pr_notify_mask_to_str(struct seq_file *m, unsigned long mask)
+{
+	bool sep = false;
+	int i;
+
+	if (!mask) {
+		seq_puts(m, "none");
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(nvmet_pr_notify_names); i++) {
+		if (!test_bit(i, &mask) || !nvmet_pr_notify_names[i])
+			continue;
+		if (sep)
+			seq_putc(m, ',');
+		seq_puts(m, nvmet_pr_notify_names[i]);
+		sep = true;
+	}
+}
+
+static int nvmet_ns_pr_show(struct seq_file *m, void *p)
+{
+	struct nvmet_ns *ns = m->private;
+	struct nvmet_pr *pr = &ns->pr;
+	struct nvmet_pr_registrant *holder, *reg;
+
+	seq_printf(m, "enable=%d\n", pr->enable);
+	if (!pr->enable)
+		return 0;
+
+	seq_printf(m, "generation=%u\n", atomic_read(&pr->generation));
+	seq_puts(m, "notify_mask=");
+	nvmet_pr_notify_mask_to_str(m, pr->notify_mask);
+	seq_putc(m, '\n');
+
+	rcu_read_lock();
+	holder = rcu_dereference(pr->holder);
+	if (holder) {
+		seq_printf(m, "rtype=%s\n",
+			   nvmet_pr_type_to_str(holder->rtype));
+		seq_printf(m, "holder=%pUb,0x%llx\n",
+			   &holder->hostid, holder->rkey);
+	} else {
+		seq_puts(m, "rtype=none\n");
+		seq_puts(m, "holder=none\n");
+	}
+
+	list_for_each_entry_rcu(reg, &pr->registrant_list, entry) {
+		seq_printf(m, "reg=%pUb,0x%llx\n",
+			   &reg->hostid, reg->rkey);
+	}
+	rcu_read_unlock();
+
+	return 0;
+}
+NVMET_DEBUGFS_ATTR(nvmet_ns_pr);
+
 void nvmet_debugfs_ns_setup(struct nvmet_ns *ns)
 {
 	char name[16];
@@ -166,6 +246,8 @@ void nvmet_debugfs_ns_setup(struct nvmet_ns *ns)
 		ns->debugfs_dir = NULL;
 		return;
 	}
+	debugfs_create_file("reservation", 0400, ns->debugfs_dir, ns,
+			    &nvmet_ns_pr_fops);
 }
 
 void nvmet_debugfs_ns_free(struct nvmet_ns *ns)
-- 
2.43.7



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

* Re: [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state
  2026-07-07 12:11 [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
  2026-07-07 12:11 ` [PATCH v2 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
  2026-07-07 12:11 ` [PATCH v2 2/2] nvmet: expose reservation state through debugfs Guixin Liu
@ 2026-07-09  5:57 ` Christoph Hellwig
  2026-07-09 13:15 ` Daniel Wagner
  2026-07-09 17:12 ` Keith Busch
  4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2026-07-09  5:57 UTC (permalink / raw)
  To: Guixin Liu
  Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Hannes Reinecke, Daniel Wagner, Shin'ichiro Kawasaki,
	linux-nvme, xlpang, oliver.yang

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>



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

* Re: [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state
  2026-07-07 12:11 [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
                   ` (2 preceding siblings ...)
  2026-07-09  5:57 ` [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Christoph Hellwig
@ 2026-07-09 13:15 ` Daniel Wagner
  2026-07-09 17:12 ` Keith Busch
  4 siblings, 0 replies; 6+ messages in thread
From: Daniel Wagner @ 2026-07-09 13:15 UTC (permalink / raw)
  To: Guixin Liu
  Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Hannes Reinecke, Shin'ichiro Kawasaki, linux-nvme, xlpang,
	oliver.yang

On Tue, Jul 07, 2026 at 08:11:12PM +0800, Guixin Liu wrote:
> This series adds debugfs support for inspecting NVMe target reservation
> (PR) state at the namespace level.
> 
> Patch 1 introduces per-namespace debugfs directories under each subsystem,
> providing the infrastructure for namespace-specific debug entries.
> 
> Patch 2 adds a 'reservation' file that exposes the persistent reservation
> state including enable status, generation counter, notification mask,
> holder information, and the full registrant list.

Looks alright, thanks!

Reviewed-by: Daniel Wagner <dwagner@suse.de>


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

* Re: [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state
  2026-07-07 12:11 [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
                   ` (3 preceding siblings ...)
  2026-07-09 13:15 ` Daniel Wagner
@ 2026-07-09 17:12 ` Keith Busch
  4 siblings, 0 replies; 6+ messages in thread
From: Keith Busch @ 2026-07-09 17:12 UTC (permalink / raw)
  To: Guixin Liu
  Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Hannes Reinecke, Daniel Wagner, Shin'ichiro Kawasaki,
	linux-nvme, xlpang, oliver.yang

On Tue, Jul 07, 2026 at 08:11:12PM +0800, Guixin Liu wrote:
> This series adds debugfs support for inspecting NVMe target reservation
> (PR) state at the namespace level.

Thanks, applied to nvme-7.3.


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

end of thread, other threads:[~2026-07-09 17:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 12:11 [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
2026-07-07 12:11 ` [PATCH v2 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
2026-07-07 12:11 ` [PATCH v2 2/2] nvmet: expose reservation state through debugfs Guixin Liu
2026-07-09  5:57 ` [PATCH v2 0/2] nvmet: add namespace-level debugfs for reservation state Christoph Hellwig
2026-07-09 13:15 ` Daniel Wagner
2026-07-09 17:12 ` Keith Busch

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