From: John Garry <john.garry@linux.dev>
To: james.bottomley@hansenpartnership.com, mkp@kernel.org
Cc: hare@suse.com, linux-nvme@lists.infradead.org,
linux-scsi@vger.kernel.org, snitzer@kernel.org,
jmeneghi@redhat.com, bmarzins@redhat.com,
dm-devel@lists.linux.dev, hch@lst.de,
michael.christie@oracle.com, John Garry <john.garry@linux.dev>
Subject: [PATCH v9 21/29] scsi-multipath: add scsi_mpath_{start,end}_request()
Date: Sun, 8 Nov 2026 20:47:25 +0000 [thread overview]
Message-ID: <20261108204733.557995-22-john.garry@linux.dev> (raw)
In-Reply-To: <20261108204733.557995-1-john.garry@linux.dev>
Add scsi_mpath_{start,end}_request() to handle updating private multipath
request data, like nvme_mpath_{start,end}_request().
New member Scsi_Host.mpath_nr_active is added. This is required for queue
depth multipath iopolicy.
For NVMe, this count is per controller. The reason is that many NSes may
be connected to a controller, so congestion should be judged at
controller level.
SCSI has no definition of a controller, but SCSI host is a comparable
concept.
Indeed, many SCSI disks may be connected to the same SCSI host, so it
makes sense to count number of active requests at this point. However,
for a transport like iSCSI Initiator over TCP/IP, we have a separate SCSI
host per SCSI device (so there the count would be same at SCSI device
level).
Signed-off-by: John Garry <john.garry@linux.dev>
---
drivers/scsi/scsi_lib.c | 8 +++-
drivers/scsi/scsi_multipath.c | 69 +++++++++++++++++++++++++++++++++++
include/scsi/scsi_cmnd.h | 9 ++++-
include/scsi/scsi_host.h | 4 ++
include/scsi/scsi_multipath.h | 11 ++++++
5 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4dbd01484b4a..13562c0ab48b 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -669,7 +669,10 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
struct scsi_device *sdev = cmd->device;
struct request_queue *q = sdev->request_queue;
- if (blk_update_request(req, error, bytes))
+ if (sdev->scsi_mpath_dev && is_mpath_request(req)) {
+ if (scsi_mpath_end_request(req, error, bytes))
+ return true;
+ } else if (blk_update_request(req, error, bytes))
return true;
if (q->limits.features & BLK_FEAT_ADD_RANDOM)
@@ -1947,6 +1950,9 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
cmd->submitter = SUBMITTED_BY_BLOCK_LAYER;
+ if (sdev->scsi_mpath_dev && is_mpath_request(req))
+ scsi_mpath_start_request(req);
+
blk_mq_start_request(req);
if (blk_mq_is_reserved_rq(req)) {
reason = shost->hostt->queue_reserved_command(shost, cmd);
diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c
index 2f47c39d8293..93a4545f1dbf 100644
--- a/drivers/scsi/scsi_multipath.c
+++ b/drivers/scsi/scsi_multipath.c
@@ -545,6 +545,75 @@ void scsi_mpath_put_head(struct scsi_mpath_head *scsi_mpath_head)
}
EXPORT_SYMBOL_GPL(scsi_mpath_put_head);
+void scsi_mpath_start_request(struct request *req)
+{
+ struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+ struct scsi_device *sdev = scmd->device;
+ struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev;
+ struct scsi_mpath_head *scsi_mpath_head =
+ scsi_mpath_dev->scsi_mpath_head;
+ struct bio *clone = req->bio, *master;
+ struct mpath_head *mpath_head = &scsi_mpath_head->mpath_head;
+ struct gendisk *disk = mpath_head->disk;
+
+ if (mpath_qd_iopolicy(&scsi_mpath_head->iopolicy) &&
+ !(scmd->flags & SCMD_MPATH_CNT_ACTIVE)) {
+ struct Scsi_Host *shost = sdev->host;
+
+ atomic_inc(&shost->mpath_nr_active);
+ scmd->flags |= SCMD_MPATH_CNT_ACTIVE;
+ }
+
+ if (blk_rq_is_passthrough(req) || !blk_queue_io_stat(disk->queue))
+ return;
+
+ if (!clone) {
+ scmd->flags &= ~SCMD_MPATH_IO_STATS;
+ return;
+ }
+
+ if (scmd->flags & SCMD_MPATH_IO_STATS)
+ return;
+
+ master = clone->bi_private;
+
+ scmd->flags |= SCMD_MPATH_IO_STATS;
+ scmd->start_time = bdev_start_io_acct(master->bi_bdev, req_op(req),
+ jiffies);
+ scmd->start_bytes = blk_rq_bytes(req);
+}
+
+bool scsi_mpath_end_request(struct request *req, blk_status_t error,
+ unsigned int nr_bytes)
+{
+ struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+ struct scsi_device *sdev = scmd->device;
+ struct block_device *bi_bdev = NULL;
+
+ if (scmd->flags & SCMD_MPATH_IO_STATS) {
+ struct bio *clone = req->bio, *master = clone->bi_private;
+
+ bi_bdev = master->bi_bdev;
+ }
+
+ if (blk_update_request(req, error, nr_bytes))
+ return true;
+
+ if (scmd->flags & SCMD_MPATH_CNT_ACTIVE) {
+ struct Scsi_Host *shost = sdev->host;
+
+ atomic_dec_if_positive(&shost->mpath_nr_active);
+ }
+
+ if (!(scmd->flags & SCMD_MPATH_IO_STATS))
+ return false;
+ bdev_end_io_acct(bi_bdev, req_op(req),
+ scmd->start_bytes >> SECTOR_SHIFT,
+ scmd->start_time);
+
+ return false;
+}
+
int __init scsi_multipath_init(void)
{
return class_register(&scsi_mpath_device_class);
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 5a8f7a45dc6d..62ffd33ba7ea 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -58,8 +58,11 @@ struct scsi_pointer {
*/
#define SCMD_FORCE_EH_SUCCESS (1 << 3)
#define SCMD_FAIL_IF_RECOVERING (1 << 4)
+#define SCMD_MPATH_IO_STATS (1 << 5)
+#define SCMD_MPATH_CNT_ACTIVE (1 << 6)
/* flags preserved across unprep / reprep */
-#define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING)
+#define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING | \
+ SCMD_MPATH_IO_STATS | SCMD_MPATH_CNT_ACTIVE)
/* for scmd->state */
#define SCMD_STATE_COMPLETE 0
@@ -146,6 +149,10 @@ struct scsi_cmnd {
* to release this memory. (The memory
* obtained by scsi_malloc is guaranteed
* to be at an address < 16Mb). */
+ #ifdef CONFIG_SCSI_MULTIPATH
+ unsigned long start_time;
+ unsigned int start_bytes;
+ #endif
int result; /* Status code from lower level driver */
};
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index daaf1247673f..8cbca6b75732 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -756,6 +756,10 @@ struct Scsi_Host {
/* Delay for runtime autosuspend */
int rpm_autosuspend_delay;
+ #ifdef CONFIG_SCSI_MULTIPATH
+ atomic_t mpath_nr_active;
+ #endif
+
/*
* We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force
diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h
index 6e50da94fc5d..dca1307c9fa4 100644
--- a/include/scsi/scsi_multipath.h
+++ b/include/scsi/scsi_multipath.h
@@ -57,6 +57,9 @@ void scsi_mpath_add_sysfs_link(struct scsi_device *sdev);
void scsi_mpath_remove_sysfs_link(struct scsi_device *sdev);
void scsi_mpath_dev_clear_path(struct scsi_mpath_device *scsi_mpath_dev);
void scsi_mpath_revalidate_paths(struct scsi_mpath_device *scsi_mpath_dev);
+void scsi_mpath_start_request(struct request *req);
+bool scsi_mpath_end_request(struct request *req, blk_status_t error,
+ unsigned int nr_bytes);
#else /* CONFIG_SCSI_MULTIPATH */
struct scsi_mpath_head {
@@ -109,5 +112,13 @@ static inline
void scsi_mpath_revalidate_paths(struct scsi_mpath_device *scsi_mpath_dev)
{
}
+static inline void scsi_mpath_start_request(struct request *req)
+{
+}
+static inline bool scsi_mpath_end_request(struct request *req, blk_status_t error,
+ unsigned int nr_bytes)
+{
+ return false;
+}
#endif /* CONFIG_SCSI_MULTIPATH */
#endif /* _SCSI_SCSI_MULTIPATH_H */
--
2.43.0
next prev parent reply other threads:[~2026-11-08 20:48 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-08 20:47 [PATCH v9 00/29] Native SCSI Multipath support John Garry
2026-11-08 20:47 ` [PATCH v9 01/29] scsi: core: Clear cmd->flags for terminal queuing error John Garry
2026-11-09 20:49 ` Bart Van Assche
2026-11-08 20:47 ` [PATCH v9 02/29] libmultipath: Add initial framework John Garry
2026-11-08 20:47 ` [PATCH v9 03/29] libmultipath: Add basic gendisk support John Garry
2026-11-08 20:47 ` [PATCH v9 04/29] libmultipath: Add path selection support John Garry
2026-11-08 21:07 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 05/29] libmultipath: Add bio handling John Garry
2026-11-08 20:47 ` [PATCH v9 06/29] libmultipath: Add support for mpath_device management John Garry
2026-11-08 20:47 ` [PATCH v9 07/29] libmultipath: Add delayed removal support John Garry
2026-11-08 21:11 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 08/29] libmultipath: Add sysfs helpers John Garry
2026-11-08 21:02 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 09/29] libmultipath: Add support for block device IOCTL John Garry
2026-11-08 21:09 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 10/29] libmultipath: Add mpath_bdev_getgeo() John Garry
2026-11-08 20:47 ` [PATCH v9 11/29] libmultipath: Add mpath_bdev_get_unique_id() John Garry
2026-11-08 20:47 ` [PATCH v9 12/29] scsi-multipath: introduce basic SCSI device support John Garry
2026-11-08 21:02 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 13/29] scsi-multipath: introduce scsi_device head structure John Garry
2026-11-08 20:47 ` [PATCH v9 14/29] scsi-multipath: provide sysfs link from to scsi_device John Garry
2026-11-08 20:47 ` [PATCH v9 15/29] scsi-multipath: support iopolicy John Garry
2026-11-08 20:47 ` [PATCH v9 16/29] scsi-multipath: clone each bio John Garry
2026-11-08 20:47 ` [PATCH v9 17/29] scsi-multipath: clear path when device is blocked John Garry
2026-11-08 21:06 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 18/29] scsi-multipath: revalidate paths upon device unblock John Garry
2026-11-08 21:08 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 19/29] scsi-multipath: failover handling John Garry
2026-11-08 21:15 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 20/29] scsi-multipath: provide callbacks for path state John Garry
2026-11-08 21:05 ` sashiko-bot
2026-11-08 20:47 ` John Garry [this message]
2026-11-08 21:28 ` [PATCH v9 21/29] scsi-multipath: add scsi_mpath_{start,end}_request() sashiko-bot
2026-11-08 20:47 ` [PATCH v9 22/29] scsi-multipath: update request for terminal request queuing error John Garry
2026-11-08 21:09 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 23/29] scsi-multipath: add delayed disk removal support John Garry
2026-11-08 20:47 ` [PATCH v9 24/29] scsi: sd: add multipath disk class John Garry
2026-11-08 20:47 ` [PATCH v9 25/29] scsi: sd: add multipath disk attr groups John Garry
2026-11-08 20:47 ` [PATCH v9 26/29] scsi: sd: support multipath disk John Garry
2026-11-08 21:23 ` sashiko-bot
2026-11-08 20:47 ` [PATCH v9 27/29] scsi: sd: add mpath_dev file John Garry
2026-11-08 20:47 ` [PATCH v9 28/29] scsi: sd: add mpath_numa_nodes dev attribute John Garry
2026-11-08 20:47 ` [PATCH v9 29/29] scsi: sd: add mpath_queue_depth " John Garry
2026-11-09 20:19 ` [PATCH v9 00/29] Native SCSI Multipath support Laurence Oberman
2026-11-10 9:05 ` John Garry
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=20261108204733.557995-22-john.garry@linux.dev \
--to=john.garry@linux.dev \
--cc=bmarzins@redhat.com \
--cc=dm-devel@lists.linux.dev \
--cc=hare@suse.com \
--cc=hch@lst.de \
--cc=james.bottomley@hansenpartnership.com \
--cc=jmeneghi@redhat.com \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=michael.christie@oracle.com \
--cc=mkp@kernel.org \
--cc=snitzer@kernel.org \
/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.