From: Guixin Liu <kanie@linux.alibaba.com>
To: Keith Busch <kbusch@kernel.org>, Jens Axboe <axboe@kernel.dk>,
Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>,
Nilay Shroff <nilay@linux.ibm.com>,
Daniel Wagner <dwagner@suse.de>, Hannes Reinecke <hare@suse.de>
Cc: linux-nvme@lists.infradead.org
Subject: [PATCH 09/11] nvmet: serve the FDP log pages
Date: Mon, 19 Oct 2026 11:36:22 +0800 [thread overview]
Message-ID: <20261019033624.402337-10-kanie@linux.alibaba.com> (raw)
In-Reply-To: <20261019033624.402337-1-kanie@linux.alibaba.com>
The bridge advertises the FDP log pages 20h to 23h as supported;
serve them.
The FDP Configurations log page (LID 20h) is constructed from the
snapshot taken at namespace enable time: one valid configuration
with a single reclaim group, the backing number of reclaim unit
handles, all of the Initially Isolated type, and the backing reclaim
unit nominal size. The page is addressed by the Endurance Group
Identifier in the Log Specific Identifier field. Hosts first
request the 16 byte header to learn the page size and then the full
page; both request sizes are served from the same construction path.
The remaining pages are owned by the backing controller and are
forwarded to it over its admin queue, addressed by the Endurance
Group Identifier of the backing endurance group, so hosts read the
real reclaim unit handle usage, counters and events of the backing
device.
Assisted-by: LLM
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
drivers/nvme/target/admin-cmd.c | 16 ++++++
drivers/nvme/target/fdp.c | 98 ++++++++++++++++++++++++++++++++-
drivers/nvme/target/nvmet.h | 14 +++++
3 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 34492cf02875a..08bec1259dd94 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -220,6 +220,16 @@ static void nvmet_execute_get_supported_log_pages(struct nvmet_req *req)
logs->lids[NVME_LOG_FEATURES] = cpu_to_le32(NVME_LIDS_LSUPP);
logs->lids[NVME_LOG_RMI] = cpu_to_le32(NVME_LIDS_LSUPP);
logs->lids[NVME_LOG_RESERVATION] = cpu_to_le32(NVME_LIDS_LSUPP);
+ if (nvmet_fdp_subsys_configured(nvmet_req_subsys(req))) {
+ logs->lids[NVME_LOG_FDP_CONFIGS] =
+ cpu_to_le32(NVME_LIDS_LSUPP);
+ logs->lids[NVME_LOG_FDP_RUH_USAGE] =
+ cpu_to_le32(NVME_LIDS_LSUPP);
+ logs->lids[NVME_LOG_FDP_STATS] =
+ cpu_to_le32(NVME_LIDS_LSUPP);
+ logs->lids[NVME_LOG_FDP_EVENTS] =
+ cpu_to_le32(NVME_LIDS_LSUPP);
+ }
status = nvmet_copy_to_sgl(req, 0, logs, sizeof(*logs));
kfree(logs);
@@ -648,6 +658,12 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req)
return nvmet_execute_get_log_page_rmi(req);
case NVME_LOG_RESERVATION:
return nvmet_execute_get_log_page_resv(req);
+ case NVME_LOG_FDP_CONFIGS:
+ return nvmet_execute_get_log_page_fdp_configs(req);
+ case NVME_LOG_FDP_RUH_USAGE:
+ case NVME_LOG_FDP_STATS:
+ case NVME_LOG_FDP_EVENTS:
+ return nvmet_fdp_log_forward(req);
}
pr_debug("unhandled lid %d on qid %d\n",
req->cmd->get_log_page.lid, req->sq->qid);
diff --git a/drivers/nvme/target/fdp.c b/drivers/nvme/target/fdp.c
index 6458efadbcb8e..8c0bc297471ec 100644
--- a/drivers/nvme/target/fdp.c
+++ b/drivers/nvme/target/fdp.c
@@ -162,7 +162,6 @@ u16 nvmet_get_feat_fdp(struct nvmet_req *req)
return 0;
}
-
static u16 nvmet_fdp_io_mgmt_check(struct nvmet_req *req)
{
if (!nvmet_fdp_enabled(req->ns))
@@ -333,3 +332,100 @@ static int nvmet_fdp_init_backend(struct nvmet_ns *ns)
return ret;
}
+void nvmet_execute_get_log_page_fdp_configs(struct nvmet_req *req)
+{
+ u32 lsi = le16_to_cpu(req->cmd->get_log_page.lsi);
+ struct nvme_fdp_config_desc *desc;
+ struct nvme_fdp_config_log *log;
+ struct nvmet_ns *ns;
+ size_t dsze, total;
+ u16 status = 0;
+ int i;
+
+ ns = nvmet_fdp_lookup_ns(req, lsi);
+ if (!ns) {
+ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
+ goto out;
+ }
+
+ dsze = ALIGN(struct_size(desc, ruhs, ns->fdp.nruh), 8);
+ total = sizeof(*log) + dsze;
+
+ log = kzalloc(req->transfer_len, GFP_KERNEL);
+ if (!log) {
+ status = NVME_SC_INTERNAL;
+ goto out_put;
+ }
+
+ if (req->transfer_len >= sizeof(*log)) {
+ /* single configuration, 0's based */
+ log->numfdpc = 0;
+ log->ver = 0;
+ log->sze = cpu_to_le32(total);
+ }
+ if (req->transfer_len >= total) {
+ desc = (void *)(log + 1);
+ desc->dsze = cpu_to_le16(dsze);
+ /* FDPCV set, FDPVWC clear, RGIF 0 for the single RG */
+ desc->fdpa = 1 << 7;
+ desc->nrg = cpu_to_le32(1);
+ desc->nruh = cpu_to_le16(ns->fdp.nruh);
+ desc->maxpids = cpu_to_le16(ns->fdp.nruh - 1);
+ desc->nns = cpu_to_le32(1);
+ desc->runs = cpu_to_le64(ns->fdp.runs);
+ /* all handles Initially Isolated */
+ for (i = 0; i < ns->fdp.nruh; i++)
+ desc->ruhs[i].ruht = 0x1;
+ }
+
+ status = nvmet_copy_to_sgl(req, 0, log, req->transfer_len);
+ kfree(log);
+out_put:
+ percpu_ref_put(&ns->ref);
+out:
+ nvmet_req_complete(req, status);
+}
+
+/*
+ * Forward an FDP log page that the backing controller owns, addressed
+ * by the Endurance Group Identifier of the backing endurance group.
+ */
+void nvmet_fdp_log_forward(struct nvmet_req *req)
+{
+ struct nvme_command c = {};
+ struct nvmet_ns *ns;
+ u16 status = 0;
+ void *buf;
+ int ret;
+
+ ns = nvmet_fdp_lookup_ns(req,
+ le16_to_cpu(req->cmd->get_log_page.lsi));
+ if (!ns) {
+ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
+ goto out;
+ }
+
+ buf = kzalloc(req->transfer_len, GFP_KERNEL);
+ if (!buf) {
+ status = NVME_SC_INTERNAL;
+ goto out_put;
+ }
+
+ c = *req->cmd;
+ c.get_log_page.nsid = cpu_to_le32(0);
+ c.get_log_page.lsi = cpu_to_le16(ns->fdp.backend_endgid);
+ ret = nvme_submit_sync_cmd(ns->fdp.backend_ctrl->admin_q, &c, buf,
+ req->transfer_len);
+ if (ret) {
+ status = ret > 0 ? ret : NVME_SC_INTERNAL;
+ goto free;
+ }
+
+ status = nvmet_copy_to_sgl(req, 0, buf, req->transfer_len);
+free:
+ kfree(buf);
+out_put:
+ percpu_ref_put(&ns->ref);
+out:
+ nvmet_req_complete(req, status);
+}
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 037c3862062ab..5bcc719973a57 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -1003,6 +1003,8 @@ u16 nvmet_set_feat_fdp(struct nvmet_req *req);
u16 nvmet_get_feat_fdp(struct nvmet_req *req);
void nvmet_execute_io_mgmt_recv(struct nvmet_req *req);
void nvmet_execute_io_mgmt_send(struct nvmet_req *req);
+void nvmet_execute_get_log_page_fdp_configs(struct nvmet_req *req);
+void nvmet_fdp_log_forward(struct nvmet_req *req);
#else
static inline bool nvmet_fdp_enabled(struct nvmet_ns *ns)
{
@@ -1035,6 +1037,18 @@ static inline void nvmet_execute_io_mgmt_send(struct nvmet_req *req)
{
nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_STATUS_DNR);
}
+static inline void nvmet_execute_get_log_page_fdp_configs(struct nvmet_req *req)
+{
+ nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_STATUS_DNR);
+}
+static inline void nvmet_fdp_log_forward(struct nvmet_req *req)
+{
+ nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_STATUS_DNR);
+}
+static inline u8 nvmet_fdp_write_stream(struct nvmet_req *req)
+{
+ return 0;
+}
#endif
/*
--
2.43.7
next prev parent reply other threads:[~2026-10-19 3:36 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 3:36 [PATCH RESEND 0/11] nvmet: FDP bridge for NVMe-oF targets Guixin Liu
2026-10-19 3:36 ` [PATCH 01/11] nvme: add the FDP wire structures for the I/O management send command Guixin Liu
2026-10-19 3:36 ` [PATCH 02/11] block: add bdev_write_stream_granularity() Guixin Liu
2026-10-19 3:36 ` [PATCH 03/11] nvme: export nvme_bdev_ops Guixin Liu
2026-10-19 3:36 ` [PATCH 04/11] nvmet: add per-namespace FDP bridge state and configuration Guixin Liu
2026-10-19 3:36 ` [PATCH 05/11] nvmet: report the Endurance Group Identifier in the CS-INDEP identify data Guixin Liu
2026-10-19 3:36 ` [PATCH 06/11] nvmet: advertise the FDP capability Guixin Liu
2026-10-19 3:36 ` [PATCH 07/11] nvmet: implement the FDP feature Guixin Liu
2026-10-19 3:45 ` sashiko-bot
2026-10-19 8:30 ` Guixin Liu
2026-10-19 3:36 ` [PATCH 08/11] nvmet: forward the FDP I/O management commands to the backing device Guixin Liu
2026-10-19 3:57 ` sashiko-bot
2026-10-19 9:44 ` Guixin Liu
2026-10-19 3:36 ` Guixin Liu [this message]
2026-10-19 4:07 ` [PATCH 09/11] nvmet: serve the FDP log pages sashiko-bot
2026-10-19 3:36 ` [PATCH 10/11] nvmet: translate placement identifiers of writes to write streams Guixin Liu
2026-10-19 3:44 ` sashiko-bot
2026-10-19 8:27 ` Guixin Liu
2026-10-19 3:36 ` [PATCH 11/11] nvmet: add an FDP write translation tracepoint Guixin Liu
2026-10-19 3:48 ` sashiko-bot
2026-10-19 8:32 ` Guixin Liu
-- strict thread matches above, loose matches on Subject: below --
2026-10-13 2:20 [PATCH 0/11] nvmet: FDP bridge for NVMe-oF targets Guixin Liu
2026-10-13 2:21 ` [PATCH 09/11] nvmet: serve the FDP log pages Guixin Liu
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=20261019033624.402337-10-kanie@linux.alibaba.com \
--to=kanie@linux.alibaba.com \
--cc=axboe@kernel.dk \
--cc=dwagner@suse.de \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=nilay@linux.ibm.com \
--cc=sagi@grimberg.me \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.