* [PATCH RFC] nvme-multipath: fix diskstats for partitions
@ 2026-07-21 11:45 John Garry
2026-07-24 5:01 ` Christoph Hellwig
0 siblings, 1 reply; 6+ messages in thread
From: John Garry @ 2026-07-21 11:45 UTC (permalink / raw)
To: hch, kbusch, sagi, axboe; +Cc: linux-nvme, John Garry, John Garry
From: John Garry <john.garry@linux.dev>
Currently diskstats for partitions are never updated:
$ ./fio_read nvme1n1p1 # run traffic on /dev/nvme1n1p1
...
$ more /proc/diskstats | grep nvme1
259 2 nvme1c1n1 49857 0 400344 768565 0 0 0 0 0 2334 768565 0 0 0 0 0 0
259 3 nvme1n1 99710 0 800680 1599285 0 0 0 0 0 2346 1599285 0 0 0 0 0 0
259 5 nvme1n1p1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
259 4 nvme1c2n1 49853 0 400336 831472 0 0 0 0 0 2315 831472 0 0 0 0 0 0
This is because we only ever update the diskstats for the multipath disk in
nvme_mpath_end_request(), and we never take into account that the original
bi_bdev may been a partition of this disk.
Functions bdev_start_io_acct() and bdev_start_io_acct() do handle
updating diskstats for a partition, in that they also update the whole
disk also (if a partition), so use the partition (if applicable) when
calling those functions.
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
Setting as an RFC as adding this extra bio field is not acceptable, but I
can't see how to lookup the original partition.
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index c850a4bf73801..14d48cdc640c8 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -194,8 +194,12 @@ void nvme_mpath_start_request(struct request *rq)
return;
nvme_req(rq)->flags |= NVME_MPATH_IO_STATS;
- nvme_req(rq)->start_time = bdev_start_io_acct(disk->part0, req_op(rq),
- jiffies);
+ if (bdev_is_partition(rq->bio->bi_orig))
+ nvme_req(rq)->start_time = bdev_start_io_acct(rq->bio->bi_orig, req_op(rq),
+ jiffies);
+ else
+ nvme_req(rq)->start_time = bdev_start_io_acct(disk->part0, req_op(rq),
+ jiffies);
}
EXPORT_SYMBOL_GPL(nvme_mpath_start_request);
@@ -208,7 +212,12 @@ void nvme_mpath_end_request(struct request *rq)
if (!(nvme_req(rq)->flags & NVME_MPATH_IO_STATS))
return;
- bdev_end_io_acct(ns->head->disk->part0, req_op(rq),
+ if (bdev_is_partition(rq->bio->bi_orig))
+ bdev_end_io_acct(rq->bio->bi_orig, req_op(rq),
+ blk_rq_bytes(rq) >> SECTOR_SHIFT,
+ nvme_req(rq)->start_time);
+ else
+ bdev_end_io_acct(ns->head->disk->part0, req_op(rq),
blk_rq_bytes(rq) >> SECTOR_SHIFT,
nvme_req(rq)->start_time);
}
@@ -543,6 +552,7 @@ static void nvme_ns_head_submit_bio(struct bio *bio)
srcu_idx = srcu_read_lock(&head->srcu);
ns = nvme_find_path(head);
if (likely(ns)) {
+ bio->bi_orig = bio->bi_bdev;
bio_set_dev(bio, ns->disk->part0);
/*
* Use BIO_REMAPPED to skip bio_check_eod() when this bio
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 8808ee76e73c0..496005aff59b3 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -210,6 +210,7 @@ typedef unsigned int blk_qc_t;
struct bio {
struct bio *bi_next; /* request queue link */
struct block_device *bi_bdev;
+ struct block_device *bi_orig;
blk_opf_t bi_opf; /* bottom bits REQ_OP, top bits
* req_flags.
*/
--
2.43.7
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH RFC] nvme-multipath: fix diskstats for partitions
2026-07-21 11:45 [PATCH RFC] nvme-multipath: fix diskstats for partitions John Garry
@ 2026-07-24 5:01 ` Christoph Hellwig
2026-07-24 7:09 ` John Garry
0 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2026-07-24 5:01 UTC (permalink / raw)
To: John Garry; +Cc: hch, kbusch, sagi, axboe, linux-nvme, John Garry
On Tue, Jul 21, 2026 at 11:45:53AM +0000, John Garry wrote:
> Setting as an RFC as adding this extra bio field is not acceptable, but I
> can't see how to lookup the original partition.
In general it is not, but you should mark this a block patch so that
Jens can better cream at you :)
I'm also not sure that supporting per-partition diskstats on a multipath
device makes too much sense, but then again there's a lot of setups
that are crazy and actually used..
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RFC] nvme-multipath: fix diskstats for partitions
2026-07-24 5:01 ` Christoph Hellwig
@ 2026-07-24 7:09 ` John Garry
2026-07-24 12:45 ` Keith Busch
0 siblings, 1 reply; 6+ messages in thread
From: John Garry @ 2026-07-24 7:09 UTC (permalink / raw)
To: Christoph Hellwig
Cc: kbusch, sagi, axboe, linux-nvme, John Garry, linux-block
On 24/07/2026 06:01, Christoph Hellwig wrote:
> On Tue, Jul 21, 2026 at 11: 45: 53AM +0000, John Garry wrote: > Setting as an
> RFC as adding this extra bio field is not acceptable, but I > can't see how to
> lookup the original partition. In general it is not, but you should mark this a
>
>
> On Tue, Jul 21, 2026 at 11:45:53AM +0000, John Garry wrote:
>> Setting as an RFC as adding this extra bio field is not acceptable, but I
>> can't see how to lookup the original partition.
>
> In general it is not, but you should mark this a block patch so that
> Jens can better cream at you :)
>
> I'm also not sure that supporting per-partition diskstats on a multipath
> device makes too much sense, but then again there's a lot of setups
> that are crazy and actually used..
>
It just seems to me that we should have same behaviour as if it were not
multipath.
So we can't use bi_private as that can be set by original bio submitter.
I was thinking that this bdev pointer could be temp stashed in bi_next
(as it should be originally NULL), but that it dodgy and maybe won't
even work.
Least worst I can think if is to alloc some temp memory per-bio in
nvme_ns_head_submit_bio() to hold this bdev pointer and original
bi_private, set bio->bi_private to that memory, and then set bi_private
back to original when we end the bio. But this is all crappy, especially
just for partition diskstats.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RFC] nvme-multipath: fix diskstats for partitions
2026-07-24 7:09 ` John Garry
@ 2026-07-24 12:45 ` Keith Busch
2026-07-24 15:29 ` John Garry
0 siblings, 1 reply; 6+ messages in thread
From: Keith Busch @ 2026-07-24 12:45 UTC (permalink / raw)
To: John Garry
Cc: Christoph Hellwig, sagi, axboe, linux-nvme, John Garry,
linux-block
On Fri, Jul 24, 2026 at 08:09:51AM +0100, John Garry wrote:
> On 24/07/2026 06:01, Christoph Hellwig wrote:
> > On Tue, Jul 21, 2026 at 11: 45: 53AM +0000, John Garry wrote: > Setting as an
> > RFC as adding this extra bio field is not acceptable, but I > can't see how to
> > lookup the original partition. In general it is not, but you should mark this a
> >
> >
> > On Tue, Jul 21, 2026 at 11:45:53AM +0000, John Garry wrote:
> > > Setting as an RFC as adding this extra bio field is not acceptable, but I
> > > can't see how to lookup the original partition.
> >
> > In general it is not, but you should mark this a block patch so that
> > Jens can better cream at you :)
> >
> > I'm also not sure that supporting per-partition diskstats on a multipath
> > device makes too much sense, but then again there's a lot of setups
> > that are crazy and actually used..
> >
>
> It just seems to me that we should have same behaviour as if it were not
> multipath.
>
> So we can't use bi_private as that can be set by original bio submitter. I
> was thinking that this bdev pointer could be temp stashed in bi_next (as it
> should be originally NULL), but that it dodgy and maybe won't even work.
Failover is corner case to consider here. We always reset the bio bdev
to the part0, so your stats will be incorrect when that happens. I think
you can quickly fix that in your proposal with the "bi_orig", though.
Can we just thread through partitions for the bio's block_device instead
of assuming part0? I know the hidden path devices skip partition
scanning, but maybe if we let it happen, then those will have the same
partition setup as the head gendisk. Then we can go right to the
disk->part_tbl for what we provide to bio_set_dev() for both submission
and failover, and everything should work out from there.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RFC] nvme-multipath: fix diskstats for partitions
2026-07-24 12:45 ` Keith Busch
@ 2026-07-24 15:29 ` John Garry
2026-07-24 15:37 ` Keith Busch
0 siblings, 1 reply; 6+ messages in thread
From: John Garry @ 2026-07-24 15:29 UTC (permalink / raw)
To: Keith Busch, John Garry
Cc: Christoph Hellwig, sagi, axboe, linux-nvme, linux-block
On 7/24/26 13:45, Keith Busch wrote:
> On Fri, Jul 24, 2026 at 08:09:51AM +0100, John Garry wrote:
>> On 24/07/2026 06:01, Christoph Hellwig wrote:
>>> On Tue, Jul 21, 2026 at 11: 45: 53AM +0000, John Garry wrote: > Setting as an
>>> RFC as adding this extra bio field is not acceptable, but I > can't see how to
>>> lookup the original partition. In general it is not, but you should mark this a
>>>
>>>
>>> On Tue, Jul 21, 2026 at 11:45:53AM +0000, John Garry wrote:
>>>> Setting as an RFC as adding this extra bio field is not acceptable, but I
>>>> can't see how to lookup the original partition.
>>>
>>> In general it is not, but you should mark this a block patch so that
>>> Jens can better cream at you :)
>>>
>>> I'm also not sure that supporting per-partition diskstats on a multipath
>>> device makes too much sense, but then again there's a lot of setups
>>> that are crazy and actually used..
>>>
>>
>> It just seems to me that we should have same behaviour as if it were not
>> multipath.
>>
>> So we can't use bi_private as that can be set by original bio submitter. I
>> was thinking that this bdev pointer could be temp stashed in bi_next (as it
>> should be originally NULL), but that it dodgy and maybe won't even work.
>
> Failover is corner case to consider here. We always reset the bio bdev
> to the part0, so your stats will be incorrect when that happens. I think
> you can quickly fix that in your proposal with the "bi_orig", though.
>
> Can we just thread through partitions for the bio's block_device instead
> of assuming part0? I know the hidden path devices skip partition
> scanning, but maybe if we let it happen, then those will have the same
> partition setup as the head gendisk. Then we can go right to the
> disk->part_tbl for what we provide to bio_set_dev() for both submission
> and failover, and everything should work out from there.
I guess that we would just scan through the per-path gendisk->part_tbl
and match somehow to lookup the partition. Maybe vs start address of
bio->bi_bdev. Or is there a simpler (and quicker) way?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RFC] nvme-multipath: fix diskstats for partitions
2026-07-24 15:29 ` John Garry
@ 2026-07-24 15:37 ` Keith Busch
0 siblings, 0 replies; 6+ messages in thread
From: Keith Busch @ 2026-07-24 15:37 UTC (permalink / raw)
To: John Garry
Cc: John Garry, Christoph Hellwig, sagi, axboe, linux-nvme,
linux-block
On Fri, Jul 24, 2026 at 04:29:08PM +0100, John Garry wrote:
> On 7/24/26 13:45, Keith Busch wrote:
> > Can we just thread through partitions for the bio's block_device instead
> > of assuming part0? I know the hidden path devices skip partition
> > scanning, but maybe if we let it happen, then those will have the same
> > partition setup as the head gendisk. Then we can go right to the
> > disk->part_tbl for what we provide to bio_set_dev() for both submission
> > and failover, and everything should work out from there.
>
> I guess that we would just scan through the per-path gendisk->part_tbl and
> match somehow to lookup the partition. Maybe vs start address of
> bio->bi_bdev. Or is there a simpler (and quicker) way?
>
This is the idea, assuming we can get the partition tables of the head
and path disks to be aligned:
---
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -543,7 +543,10 @@ static void nvme_ns_head_submit_bio(struct bio *bio)
srcu_idx = srcu_read_lock(&head->srcu);
ns = nvme_find_path(head);
if (likely(ns)) {
- bio_set_dev(bio, ns->disk->part0);
+ struct block_device *bdev;
+
+ bdev = xa_load(&ns->disk->part_tbl, bdev_partno(bio->bi_bdev));
+ bio_set_dev(bio, bdev);
/*
* Use BIO_REMAPPED to skip bio_check_eod() when this bio
* enters submit_bio_noacct() for the per-path device. The EOD
--
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-24 15:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 11:45 [PATCH RFC] nvme-multipath: fix diskstats for partitions John Garry
2026-07-24 5:01 ` Christoph Hellwig
2026-07-24 7:09 ` John Garry
2026-07-24 12:45 ` Keith Busch
2026-07-24 15:29 ` John Garry
2026-07-24 15:37 ` Keith Busch
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.