From: sashiko-bot@kernel.org
To: "John Garry" <john.garry@linux.dev>,
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
Subject: Re: [PATCH v9 21/29] scsi-multipath: add scsi_mpath_{start,end}_request()
Date: Sun, 08 Nov 2026 21:28:05 +0000 [thread overview]
Message-ID: <sashiko-outbox-204075@kernel.org> (raw)
In-Reply-To: <20261108204733.557995-22-john.garry@linux.dev>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] scsi: multipath: premature bio completion in
scsi_mpath_end_request()
- [Medium] scsi-multipath: mismatched bdev I/O accounting in
scsi_mpath_end_request()
--
commit 29255340e39c30a34f5cb1da674871fdd2c627ea
Author: John Garry <john.garry@linux.dev>
scsi-multipath: add scsi_mpath_{start,end}_request()
This commit adds scsi_mpath_start_request() and scsi_mpath_end_request()
to track per-host active multipath requests for the queue-depth I/O policy
and perform block device I/O accounting on multipath requests.
> diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c
> index 2f47c39d82936..93a4545f1dbf7 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;
> + }
[Severity: Medium]
Can scsi_mpath_start_request() and scsi_mpath_end_request() account I/O
against different block_device structures when a merged request completes
partially?
scsi_mpath_clone_bio() directs all clone bios to the underlying path
disk's part0 while storing the original bio in clone->bi_private.
Contiguous clone bios from adjacent partitions on mpath_head->disk can
therefore be merged into a single request on sdev->request_queue.
When that request starts, scsi_mpath_start_request() calls
bdev_start_io_acct() on the first bio's master->bi_bdev and sets
SCMD_MPATH_IO_STATS. If a partial completion advances req->bio past the
first bio (returning true from blk_update_request()), the final call to
scsi_mpath_end_request() re-derives bi_bdev from the remaining bio's
master->bi_bdev and calls bdev_end_io_acct() on the second partition,
leaking in_flight on the first partition and underflowing it on the
second.
Accounting against mpath_head->disk->part0 in both functions (or saving
the accounted block_device) would keep the start and end calls paired.
> +
> + 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;
> +}
[Severity: Medium]
Does calling blk_update_request() before updating shost->mpath_nr_active
and calling bdev_end_io_acct() complete master_bio too early?
blk_update_request() runs bio_endio(clone) -> scsi_mpath_clone_end_io(),
which either schedules mpath_head->requeue_work on a path error or calls
bio_endio(master_bio). Because mpath_head->disk is bio-based,
__submit_bio() drops its queue reference as soon as
mpath_bdev_submit_bio() returns, so nothing pins bi_bdev once master_bio
completes:
CPU0 CPU1
scsi_mpath_end_request()
blk_update_request()
...
scsi_mpath_clone_end_io()
bio_endio(master_bio)
blkdev_put()
bdev_del_partition()
...
bdev_free_inode()
free_percpu(bdev->bd_stats)
bdev_end_io_acct(bi_bdev, ...)
<-- use-after-free on bi_bdev
In addition, when scsi_mpath_clone_end_io() triggers failover or a
caller immediately submits dependent I/O under MPATH_IOPOLICY_QD,
mpath_queue_depth_path() reads shost->mpath_nr_active before this request
has decremented it.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261108204733.557995-1-john.garry@linux.dev?part=21
next prev parent reply other threads:[~2026-11-08 21:28 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 ` [PATCH v9 21/29] scsi-multipath: add scsi_mpath_{start,end}_request() John Garry
2026-11-08 21:28 ` sashiko-bot [this message]
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=sashiko-outbox-204075@kernel.org \
--to=sashiko-bot@kernel.org \
--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=john.garry@linux.dev \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=michael.christie@oracle.com \
--cc=mkp@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--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.