From: John Garry <john.g.garry@oracle.com>
To: Nilay Shroff <nilay@linux.ibm.com>, linux-nvme@lists.infradead.org
Cc: hare@suse.de, kbusch@kernel.org, hch@lst.de, sagi@grimberg.me,
dwagner@suse.de, kanie@linux.alibaba.com, jmeneghi@redhat.com,
randyj@purestorage.com, martin.petersen@oracle.com,
gjoyce@linux.ibm.com
Subject: Re: [PATCH v7 3/9] nvme-multipath: pass I/O type to nvme_find_path()
Date: Mon, 10 Aug 2026 09:57:16 +0100 [thread overview]
Message-ID: <f6daf09b-338d-4518-9d1a-a172b3c2bef5@oracle.com> (raw)
In-Reply-To: <20260809100825.2014133-4-nilay@linux.ibm.com>
> @@ -741,6 +752,7 @@ int nvme_ns_head_ioctl(struct block_device *bdev, blk_mode_t mode,
> long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
> unsigned long arg)
> {
> + u8 opcode;
why declared at the top?
> bool open_for_write = file->f_mode & FMODE_WRITE;
> struct cdev *cdev = file_inode(file)->i_cdev;
> struct nvme_ns_head *head =
> @@ -748,9 +760,19 @@ long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
> void __user *argp = (void __user *)arg;
> struct nvme_ns *ns;
> int srcu_idx, ret = -EWOULDBLOCK;
> + unsigned int op_type = NVME_STAT_OTHER;
> +
> + if (cmd == NVME_IOCTL_SUBMIT_IO) {
> + if (get_user(opcode, (u8 *)argp))
> + return -EFAULT;
> + if (opcode == nvme_cmd_write)
> + op_type = NVME_STAT_WRITE;
> + else if (opcode == nvme_cmd_read)
> + op_type = NVME_STAT_READ;
> + }
>
> srcu_idx = srcu_read_lock(&head->srcu);
> - ns = nvme_find_path(head);
> + ns = nvme_find_path(head, op_type);
> if (!ns)
> goto out_unlock;
>
> @@ -770,9 +792,19 @@ int nvme_ns_head_chr_uring_cmd(struct io_uring_cmd *ioucmd,
> struct cdev *cdev = file_inode(ioucmd->file)->i_cdev;
> struct nvme_ns_head *head = container_of(cdev, struct nvme_ns_head, cdev);
> int srcu_idx = srcu_read_lock(&head->srcu);
> - struct nvme_ns *ns = nvme_find_path(head);
> + struct nvme_ns *ns;
> int ret = -EINVAL;
> + const struct nvme_uring_cmd *cmd = io_uring_sqe128_cmd(ioucmd->sqe,
> + struct nvme_uring_cmd);
> + unsigned int op_type = NVME_STAT_OTHER;
> + __u8 opcode = READ_ONCE(cmd->opcode);
> +
> + if (opcode == nvme_cmd_write)
> + op_type = NVME_STAT_WRITE;
> + else if (opcode == nvme_cmd_read)
> + op_type = NVME_STAT_READ;
nit: I think that having a final else leg to set op_type is nicer than
setting to NVME_STAT_OTHER at init time (and overwriting in some cases).
>
> + ns = nvme_find_path(head, op_type);
> if (ns)
> ret = nvme_ns_uring_cmd(ns, ioucmd, issue_flags);
> srcu_read_unlock(&head->srcu, srcu_idx);
> diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
> index 9b9a657fa330..8c20ff516e61 100644
> --- a/drivers/nvme/host/multipath.c
> +++ b/drivers/nvme/host/multipath.c
> @@ -460,7 +460,8 @@ static struct nvme_ns *nvme_numa_path(struct nvme_ns_head *head)
> return ns;
> }
>
> -inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head)
> +inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head,
> + unsigned int op_type)
> {
> switch (READ_ONCE(head->subsys->iopolicy)) {
> case NVME_IOPOLICY_QD:
> @@ -522,7 +523,7 @@ static void nvme_ns_head_submit_bio(struct bio *bio)
> return;
>
> srcu_idx = srcu_read_lock(&head->srcu);
> - ns = nvme_find_path(head);
> + ns = nvme_find_path(head, __nvme_data_dir(bio_op(bio)));
It's a but unfortunate that we have to find op_type even for when not
using the latency iopolicy.
> if (likely(ns)) {
> bio_set_dev(bio, ns->disk->part0);
> /*
> @@ -572,7 +573,7 @@ static int nvme_ns_head_get_unique_id(struct gendisk *disk, u8 id[16],
> int srcu_idx, ret = -EWOULDBLOCK;
>
> srcu_idx = srcu_read_lock(&head->srcu);
> - ns = nvme_find_path(head);
> + ns = nvme_find_path(head, NVME_STAT_OTHER);
> if (ns)
> ret = nvme_ns_get_unique_id(ns, id, type);
> srcu_read_unlock(&head->srcu, srcu_idx);
> @@ -588,7 +589,7 @@ static int nvme_ns_head_report_zones(struct gendisk *disk, sector_t sector,
> int srcu_idx, ret = -EWOULDBLOCK;
>
> srcu_idx = srcu_read_lock(&head->srcu);
> - ns = nvme_find_path(head);
> + ns = nvme_find_path(head, NVME_STAT_OTHER);
> if (ns)
> ret = nvme_ns_report_zones(ns, sector, nr_zones, args);
> srcu_read_unlock(&head->srcu, srcu_idx);
> diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
> index 824651cc898d..8a9ec502912d 100644
> --- a/drivers/nvme/host/nvme.h
> +++ b/drivers/nvme/host/nvme.h
> @@ -520,6 +520,13 @@ struct nvme_ns_ids {
> u8 csi;
> };
>
> +enum nvme_stat_group {
> + NVME_STAT_READ,
> + NVME_STAT_WRITE,
> + NVME_STAT_OTHER,
Would NVME_STAT_OTHER ever be used in high frequency scenarios such that
it is worth having its own type? If not, could NVME_STAT_READ be reused?
> + NVME_NUM_STAT_GROUPS
Can these ever be used for non-mulitpath? I just wonder why multipath or
similar is not in the name
> +};
> +
> /*
> * Anchor structure for namespaces. There is one for each namespace in a
> * NVMe subsystem that any of our controllers can see, and the namespace
> @@ -1032,7 +1039,39 @@ extern const struct attribute_group *nvme_dev_attr_groups[];
> extern const struct block_device_operations nvme_bdev_ops;
>
> void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl);
> -struct nvme_ns *nvme_find_path(struct nvme_ns_head *head);
> +struct nvme_ns *nvme_find_path(struct nvme_ns_head *head, unsigned int op_type);
> +
> +static inline int __nvme_data_dir(const enum req_op op)
> +{
This returns an int (so not strongly typed), which is going to be
NVME_STAT_READ, NVME_STAT_WRITE, or NVME_STAT_OTHER. From the function
name, I am not sure if that it expected. Some might expect READ or WRITE
returned. 'stat' should be in the name, or similar.
> + if (op == REQ_OP_READ)
> + return NVME_STAT_READ;
> + else if (op == REQ_OP_WRITE)
> + return NVME_STAT_WRITE;
> + else
> + return NVME_STAT_OTHER;> +}
> +
> +static inline int __nvme_data_dir_passthru(enum nvme_opcode op)
> +{
As __nvme_data_dir
> + if (op == nvme_cmd_read)
> + return NVME_STAT_READ;
> + else if (op == nvme_cmd_write)
> + return NVME_STAT_WRITE;
> + else
> + return NVME_STAT_OTHER;
> +}
> +
> +static inline int nvme_data_dir(struct request *req)
As __nvme_data_dir
> +{
> + if (blk_rq_is_passthrough(req)) {
> + struct nvme_request *nr = nvme_req(req);
> +
> + return __nvme_data_dir_passthru(nr->cmd->common.opcode);
> + }
> +
> + return __nvme_data_dir(req_op(req));
> +}
> +
> #ifdef CONFIG_NVME_MULTIPATH
next prev parent reply other threads:[~2026-08-10 8:57 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-09 10:07 [PATCH v7 0/9] nvme-multipath: introduce latency I/O policy Nilay Shroff
2026-08-09 10:07 ` [PATCH v7 1/9] block: expose blk_stat_{enable,disable}_accounting() to drivers Nilay Shroff
2026-08-10 8:18 ` John Garry
2026-08-09 10:07 ` [PATCH v7 2/9] block: record I/O request start time for passthru request Nilay Shroff
2026-08-10 6:44 ` Hannes Reinecke
2026-08-09 10:07 ` [PATCH v7 3/9] nvme-multipath: pass I/O type to nvme_find_path() Nilay Shroff
2026-08-10 8:57 ` John Garry [this message]
2026-08-09 10:07 ` [PATCH v7 4/9] nvme-multipath: add support for latency I/O policy Nilay Shroff
2026-08-10 8:12 ` John Garry
2026-08-10 10:46 ` John Garry
2026-08-09 10:08 ` [PATCH v7 5/9] nvme: add generic debugfs support Nilay Shroff
2026-08-09 10:08 ` [PATCH v7 6/9] nvme-multipath: add debugfs attribute latency_ewma_shift Nilay Shroff
2026-08-09 10:08 ` [PATCH v7 7/9] nvme-multipath: add debugfs attribute latency_batch_timeout Nilay Shroff
2026-08-09 10:08 ` [PATCH v7 8/9] nvme-multipath: add debugfs attribute latency_stat Nilay Shroff
2026-08-09 10:08 ` [PATCH v7 9/9] nvme-multipath: add documentation for latency I/O policy Nilay Shroff
2026-08-10 6:45 ` Hannes Reinecke
2026-08-10 7:50 ` [PATCH v7 0/9] nvme-multipath: introduce " John Garry
2026-08-10 9:43 ` 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=f6daf09b-338d-4518-9d1a-a172b3c2bef5@oracle.com \
--to=john.g.garry@oracle.com \
--cc=dwagner@suse.de \
--cc=gjoyce@linux.ibm.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=jmeneghi@redhat.com \
--cc=kanie@linux.alibaba.com \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=martin.petersen@oracle.com \
--cc=nilay@linux.ibm.com \
--cc=randyj@purestorage.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox