* [PATCHv14 00/11] block write streams with nvme fdp
@ 2024-12-11 18:35 ` Keith Busch
2024-12-11 18:35 ` [PATCHv14 10/11] nvme: register fdp parameters with the block layer Keith Busch
2024-12-12 11:39 ` [PATCHv14 00/11] block write streams with nvme fdp Kanchan Joshi
0 siblings, 2 replies; 6+ messages in thread
From: Keith Busch @ 2024-12-11 18:35 UTC (permalink / raw)
To: axboe, hch, linux-block, linux-nvme, linux-fsdevel, io-uring
Cc: sagi, asml.silence, anuj20.g, joshi.k, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Previous discussion:
https://lore.kernel.org/linux-nvme/20241210194722.1905732-1-kbusch@meta.com/T/#u
Changes from v13:
Fixed up printing size_t format (kernel test robot)
Use %d for endgid (John)
Removed bdev write stream granularity helper (no user in this series)
(John)
Clamp variable size FDP config log page size to max order (Hannes)
Ensure the log descriptor sizes make sense (Hannes)
Comment typos (Nitesh)
Commit log description fix for where to find the write stream
parameters (Nitesh).
Christoph Hellwig (7):
fs: add a write stream field to the kiocb
block: add a bi_write_stream field
block: introduce a write_stream_granularity queue limit
block: expose write streams for block device nodes
nvme: add a nvme_get_log_lsi helper
nvme: pass a void pointer to nvme_get/set_features for the result
nvme: add FDP definitions
Keith Busch (4):
block: introduce max_write_streams queue limit
io_uring: enable per-io write streams
nvme: register fdp parameters with the block layer
nvme: use fdp streams if write stream is provided
Documentation/ABI/stable/sysfs-block | 15 +++
block/bio.c | 2 +
block/blk-crypto-fallback.c | 1 +
block/blk-merge.c | 4 +
block/blk-sysfs.c | 6 +
block/bounce.c | 1 +
block/fops.c | 23 ++++
drivers/nvme/host/core.c | 192 ++++++++++++++++++++++++++-
drivers/nvme/host/nvme.h | 7 +-
include/linux/blk_types.h | 1 +
include/linux/blkdev.h | 10 ++
include/linux/fs.h | 1 +
include/linux/nvme.h | 77 +++++++++++
include/uapi/linux/io_uring.h | 4 +
io_uring/io_uring.c | 2 +
io_uring/rw.c | 1 +
16 files changed, 341 insertions(+), 6 deletions(-)
--
2.43.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCHv14 10/11] nvme: register fdp parameters with the block layer
2024-12-11 18:35 ` [PATCHv14 00/11] block write streams with nvme fdp Keith Busch
@ 2024-12-11 18:35 ` Keith Busch
2024-12-12 13:14 ` Hannes Reinecke
` (2 more replies)
2024-12-12 11:39 ` [PATCHv14 00/11] block write streams with nvme fdp Kanchan Joshi
1 sibling, 3 replies; 6+ messages in thread
From: Keith Busch @ 2024-12-11 18:35 UTC (permalink / raw)
To: axboe, hch, linux-block, linux-nvme, linux-fsdevel, io-uring
Cc: sagi, asml.silence, anuj20.g, joshi.k, Keith Busch
From: Keith Busch <kbusch@kernel.org>
Register the device data placement limits if supported. This is just
registering the limits with the block layer. Nothing beyond reporting
these attributes is happening in this patch.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/nvme/host/core.c | 145 +++++++++++++++++++++++++++++++++++++++
drivers/nvme/host/nvme.h | 2 +
2 files changed, 147 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index c2a3585a3fa59..2392373415fd6 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -23,6 +23,7 @@
#include <linux/pm_qos.h>
#include <linux/ratelimit.h>
#include <linux/unaligned.h>
+#include <linux/vmalloc.h>
#include "nvme.h"
#include "fabrics.h"
@@ -38,6 +39,8 @@ struct nvme_ns_info {
u32 nsid;
__le32 anagrpid;
u8 pi_offset;
+ u16 endgid;
+ u64 runs;
bool is_shared;
bool is_readonly;
bool is_ready;
@@ -1613,6 +1616,7 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
info->is_ready = true;
+ info->endgid = le16_to_cpu(id->endgid);
if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) {
dev_info(ctrl->device,
"Ignoring bogus Namespace Identifiers\n");
@@ -1653,6 +1657,7 @@ static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl,
info->is_ready = id->nstat & NVME_NSTAT_NRDY;
info->is_rotational = id->nsfeat & NVME_NS_ROTATIONAL;
info->no_vwc = id->nsfeat & NVME_NS_VWC_NOT_PRESENT;
+ info->endgid = le16_to_cpu(id->endgid);
}
kfree(id);
return ret;
@@ -2147,6 +2152,132 @@ static int nvme_update_ns_info_generic(struct nvme_ns *ns,
return ret;
}
+static int nvme_query_fdp_granularity(struct nvme_ctrl *ctrl,
+ struct nvme_ns_info *info, u8 fdp_idx)
+{
+ struct nvme_fdp_config_log hdr, *h;
+ struct nvme_fdp_config_desc *desc;
+ size_t size = sizeof(hdr);
+ void *log, *end;
+ int i, n, ret;
+
+ ret = nvme_get_log_lsi(ctrl, 0, NVME_LOG_FDP_CONFIGS, 0,
+ NVME_CSI_NVM, &hdr, size, 0, info->endgid);
+ if (ret) {
+ dev_warn(ctrl->device,
+ "FDP configs log header status:0x%x endgid:%d\n", ret,
+ info->endgid);
+ return ret;
+ }
+
+ size = le32_to_cpu(hdr.sze);
+ if (size > PAGE_SIZE * MAX_ORDER_NR_PAGES) {
+ dev_warn(ctrl->device, "FDP config size too large:%zu\n",
+ size);
+ return 0;
+ }
+
+ h = vmalloc(size);
+ if (!h)
+ return -ENOMEM;
+
+ ret = nvme_get_log_lsi(ctrl, 0, NVME_LOG_FDP_CONFIGS, 0,
+ NVME_CSI_NVM, h, size, 0, info->endgid);
+ if (ret) {
+ dev_warn(ctrl->device,
+ "FDP configs log status:0x%x endgid:%d\n", ret,
+ info->endgid);
+ goto out;
+ }
+
+ n = le16_to_cpu(h->numfdpc) + 1;
+ if (fdp_idx > n) {
+ dev_warn(ctrl->device, "FDP index:%d out of range:%d\n",
+ fdp_idx, n);
+ /* Proceed without registering FDP streams */
+ ret = 0;
+ goto out;
+ }
+
+ log = h + 1;
+ desc = log;
+ end = log + size - sizeof(*h);
+ for (i = 0; i < fdp_idx; i++) {
+ log += le16_to_cpu(desc->dsze);
+ desc = log;
+ if (log >= end) {
+ dev_warn(ctrl->device,
+ "FDP invalid config descriptor list\n");
+ ret = 0;
+ goto out;
+ }
+ }
+
+ if (le32_to_cpu(desc->nrg) > 1) {
+ dev_warn(ctrl->device, "FDP NRG > 1 not supported\n");
+ ret = 0;
+ goto out;
+ }
+
+ info->runs = le64_to_cpu(desc->runs);
+out:
+ kvfree(h);
+ return ret;
+}
+
+static int nvme_query_fdp_info(struct nvme_ns *ns, struct nvme_ns_info *info)
+{
+ struct nvme_ns_head *head = ns->head;
+ struct nvme_ctrl *ctrl = ns->ctrl;
+ struct nvme_fdp_ruh_status *ruhs;
+ struct nvme_fdp_config fdp;
+ struct nvme_command c = {};
+ size_t size;
+ int ret;
+
+ /*
+ * The FDP configuration is static for the lifetime of the namespace,
+ * so return immediately if we've already registered this namespace's
+ * streams.
+ */
+ if (head->nr_plids)
+ return 0;
+
+ ret = nvme_get_features(ctrl, NVME_FEAT_FDP, info->endgid, NULL, 0,
+ &fdp);
+ if (ret) {
+ dev_warn(ctrl->device, "FDP get feature status:0x%x\n", ret);
+ return ret;
+ }
+
+ if (!(fdp.flags & FDPCFG_FDPE))
+ return 0;
+
+ ret = nvme_query_fdp_granularity(ctrl, info, fdp.fdpcidx);
+ if (!info->runs)
+ return ret;
+
+ size = struct_size(ruhs, ruhsd, S8_MAX - 1);
+ ruhs = kzalloc(size, GFP_KERNEL);
+ if (!ruhs)
+ return -ENOMEM;
+
+ c.imr.opcode = nvme_cmd_io_mgmt_recv;
+ c.imr.nsid = cpu_to_le32(head->ns_id);
+ c.imr.mo = NVME_IO_MGMT_RECV_MO_RUHS;
+ c.imr.numd = cpu_to_le32(nvme_bytes_to_numd(size));
+ ret = nvme_submit_sync_cmd(ns->queue, &c, ruhs, size);
+ if (ret) {
+ dev_warn(ctrl->device, "FDP io-mgmt status:0x%x\n", ret);
+ goto free;
+ }
+
+ head->nr_plids = le16_to_cpu(ruhs->nruhsd);
+free:
+ kfree(ruhs);
+ return ret;
+}
+
static int nvme_update_ns_info_block(struct nvme_ns *ns,
struct nvme_ns_info *info)
{
@@ -2183,6 +2314,12 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
goto out;
}
+ if (ns->ctrl->ctratt & NVME_CTRL_ATTR_FDPS) {
+ ret = nvme_query_fdp_info(ns, info);
+ if (ret < 0)
+ goto out;
+ }
+
blk_mq_freeze_queue(ns->disk->queue);
ns->head->lba_shift = id->lbaf[lbaf].ds;
ns->head->nuse = le64_to_cpu(id->nuse);
@@ -2216,6 +2353,12 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
if (!nvme_init_integrity(ns->head, &lim, info))
capacity = 0;
+ lim.max_write_streams = ns->head->nr_plids;
+ if (lim.max_write_streams)
+ lim.write_stream_granularity = max(info->runs, U32_MAX);
+ else
+ lim.write_stream_granularity = 0;
+
ret = queue_limits_commit_update(ns->disk->queue, &lim);
if (ret) {
blk_mq_unfreeze_queue(ns->disk->queue);
@@ -2318,6 +2461,8 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
ns->head->disk->flags |= GENHD_FL_HIDDEN;
else
nvme_init_integrity(ns->head, &lim, info);
+ lim.max_write_streams = ns_lim->max_write_streams;
+ lim.write_stream_granularity = ns_lim->write_stream_granularity;
ret = queue_limits_commit_update(ns->head->disk->queue, &lim);
set_capacity_and_notify(ns->head->disk, get_capacity(ns->disk));
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index c1995d89ffdb8..4b412cd8001f1 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -491,6 +491,8 @@ struct nvme_ns_head {
struct device cdev_device;
struct gendisk *disk;
+
+ u16 nr_plids;
#ifdef CONFIG_NVME_MULTIPATH
struct bio_list requeue_list;
spinlock_t requeue_lock;
--
2.43.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCHv14 00/11] block write streams with nvme fdp
2024-12-11 18:35 ` [PATCHv14 00/11] block write streams with nvme fdp Keith Busch
2024-12-11 18:35 ` [PATCHv14 10/11] nvme: register fdp parameters with the block layer Keith Busch
@ 2024-12-12 11:39 ` Kanchan Joshi
1 sibling, 0 replies; 6+ messages in thread
From: Kanchan Joshi @ 2024-12-12 11:39 UTC (permalink / raw)
To: Keith Busch, axboe, hch, linux-block, linux-nvme, linux-fsdevel,
io-uring
Cc: sagi, asml.silence, anuj20.g, Keith Busch
For
> 16 files changed, 341 insertions(+), 6 deletions(-)
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCHv14 10/11] nvme: register fdp parameters with the block layer
2024-12-11 18:35 ` [PATCHv14 10/11] nvme: register fdp parameters with the block layer Keith Busch
@ 2024-12-12 13:14 ` Hannes Reinecke
[not found] ` <CGME20241213060117epcas5p33e93030b04f8d51f0367d375faa2adaf@epcas5p3.samsung.com>
2024-12-16 16:12 ` Christoph Hellwig
2 siblings, 0 replies; 6+ messages in thread
From: Hannes Reinecke @ 2024-12-12 13:14 UTC (permalink / raw)
To: Keith Busch, axboe, hch, linux-block, linux-nvme, linux-fsdevel,
io-uring
Cc: sagi, asml.silence, anuj20.g, joshi.k, Keith Busch
On 12/11/24 19:35, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
>
> Register the device data placement limits if supported. This is just
> registering the limits with the block layer. Nothing beyond reporting
> these attributes is happening in this patch.
>
> Signed-off-by: Keith Busch <kbusch@kernel.org>
> ---
> drivers/nvme/host/core.c | 145 +++++++++++++++++++++++++++++++++++++++
> drivers/nvme/host/nvme.h | 2 +
> 2 files changed, 147 insertions(+)
>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCHv14 10/11] nvme: register fdp parameters with the block layer
[not found] ` <CGME20241213060117epcas5p33e93030b04f8d51f0367d375faa2adaf@epcas5p3.samsung.com>
@ 2024-12-13 5:53 ` Nitesh Shetty
0 siblings, 0 replies; 6+ messages in thread
From: Nitesh Shetty @ 2024-12-13 5:53 UTC (permalink / raw)
To: Keith Busch
Cc: axboe, hch, linux-block, linux-nvme, linux-fsdevel, io-uring,
sagi, asml.silence, anuj20.g, joshi.k, Keith Busch
[-- Attachment #1: Type: text/plain, Size: 375 bytes --]
On 11/12/24 10:35AM, Keith Busch wrote:
>From: Keith Busch <kbusch@kernel.org>
>
>Register the device data placement limits if supported. This is just
>registering the limits with the block layer. Nothing beyond reporting
>these attributes is happening in this patch.
>
>Signed-off-by: Keith Busch <kbusch@kernel.org>
>---
Reviewed-by: Nitesh Shetty <nj.shetty@samsung.com>
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCHv14 10/11] nvme: register fdp parameters with the block layer
2024-12-11 18:35 ` [PATCHv14 10/11] nvme: register fdp parameters with the block layer Keith Busch
2024-12-12 13:14 ` Hannes Reinecke
[not found] ` <CGME20241213060117epcas5p33e93030b04f8d51f0367d375faa2adaf@epcas5p3.samsung.com>
@ 2024-12-16 16:12 ` Christoph Hellwig
2 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2024-12-16 16:12 UTC (permalink / raw)
To: Keith Busch
Cc: axboe, hch, linux-block, linux-nvme, linux-fsdevel, io-uring,
sagi, asml.silence, anuj20.g, joshi.k, Keith Busch
On Wed, Dec 11, 2024 at 10:35:13AM -0800, Keith Busch wrote:
> + size = le32_to_cpu(hdr.sze);
> + if (size > PAGE_SIZE * MAX_ORDER_NR_PAGES) {
> + dev_warn(ctrl->device, "FDP config size too large:%zu\n",
> + size);
> + return 0;
> + h = vmalloc(size);
> + if (!h)
> + return -ENOMEM;
Isn't an unconditional vmalloc here for something that usually should
have less than a handful of descriptors a little aggressive? I'd use
kvmalloc here to get the best of both worlds, and the free path seems
to already use kvfree anyway.
Otherwise the incremental changes vs the previous version for the entire
series look good to me.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-12-16 16:13 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CGME20241211190851epcas5p2a359c12000fc73df8920e4801563504c@epcas5p2.samsung.com>
2024-12-11 18:35 ` [PATCHv14 00/11] block write streams with nvme fdp Keith Busch
2024-12-11 18:35 ` [PATCHv14 10/11] nvme: register fdp parameters with the block layer Keith Busch
2024-12-12 13:14 ` Hannes Reinecke
[not found] ` <CGME20241213060117epcas5p33e93030b04f8d51f0367d375faa2adaf@epcas5p3.samsung.com>
2024-12-13 5:53 ` Nitesh Shetty
2024-12-16 16:12 ` Christoph Hellwig
2024-12-12 11:39 ` [PATCHv14 00/11] block write streams with nvme fdp Kanchan Joshi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox