Skip to content

Commit 110234d

Browse files
keithbuschaxboe
authored andcommitted
block: enable passthrough command statistics
Applications using the passthrough interfaces for IO want to continue seeing the disk stats. These requests had been fenced off from this block layer feature. While the block layer doesn't necessarily know what a passthrough command does, we do know the data size and direction, which is enough to account for the command's stats. Since tracking these has the potential to produce unexpected results, the passthrough stats are locked behind a new queue flag that needs to be enabled with the /sys/block/<dev>/queue/iostats_passthrough attribute. Signed-off-by: Keith Busch <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent d51c9cd commit 110234d

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

Documentation/ABI/stable/sysfs-block

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,13 @@ Description:
424424
[RW] This file is used to control (on/off) the iostats
425425
accounting of the disk.
426426

427+
What: /sys/block/<disk>/queue/iostats_passthrough
428+
Date: October 2024
429+
430+
Description:
431+
[RW] This file is used to control (on/off) the iostats
432+
accounting of the disk for passthrough commands.
433+
427434

428435
What: /sys/block/<disk>/queue/logical_block_size
429436
Date: May 2009

block/blk-mq.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,13 +988,43 @@ static inline void blk_account_io_done(struct request *req, u64 now)
988988
}
989989
}
990990

991+
static inline bool blk_rq_passthrough_stats(struct request *req)
992+
{
993+
struct bio *bio = req->bio;
994+
995+
if (!blk_queue_passthrough_stat(req->q))
996+
return false;
997+
998+
/* Requests without a bio do not transfer data. */
999+
if (!bio)
1000+
return false;
1001+
1002+
/*
1003+
* Stats are accumulated in the bdev, so must have one attached to a
1004+
* bio to track stats. Most drivers do not set the bdev for passthrough
1005+
* requests, but nvme is one that will set it.
1006+
*/
1007+
if (!bio->bi_bdev)
1008+
return false;
1009+
1010+
/*
1011+
* We don't know what a passthrough command does, but we know the
1012+
* payload size and data direction. Ensuring the size is aligned to the
1013+
* block size filters out most commands with payloads that don't
1014+
* represent sector access.
1015+
*/
1016+
if (blk_rq_bytes(req) & (bdev_logical_block_size(bio->bi_bdev) - 1))
1017+
return false;
1018+
return true;
1019+
}
1020+
9911021
static inline void blk_account_io_start(struct request *req)
9921022
{
9931023
trace_block_io_start(req);
9941024

9951025
if (!blk_queue_io_stat(req->q))
9961026
return;
997-
if (blk_rq_is_passthrough(req))
1027+
if (blk_rq_is_passthrough(req) && !blk_rq_passthrough_stats(req))
9981028
return;
9991029

10001030
req->rq_flags |= RQF_IO_STAT;

block/blk-sysfs.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,34 @@ static ssize_t queue_nr_zones_show(struct gendisk *disk, char *page)
272272
return queue_var_show(disk_nr_zones(disk), page);
273273
}
274274

275+
static ssize_t queue_iostats_passthrough_show(struct gendisk *disk, char *page)
276+
{
277+
return queue_var_show(blk_queue_passthrough_stat(disk->queue), page);
278+
}
279+
280+
static ssize_t queue_iostats_passthrough_store(struct gendisk *disk,
281+
const char *page, size_t count)
282+
{
283+
struct queue_limits lim;
284+
unsigned long ios;
285+
ssize_t ret;
286+
287+
ret = queue_var_store(&ios, page, count);
288+
if (ret < 0)
289+
return ret;
290+
291+
lim = queue_limits_start_update(disk->queue);
292+
if (ios)
293+
lim.flags |= BLK_FLAG_IOSTATS_PASSTHROUGH;
294+
else
295+
lim.flags &= ~BLK_FLAG_IOSTATS_PASSTHROUGH;
296+
297+
ret = queue_limits_commit_update(disk->queue, &lim);
298+
if (ret)
299+
return ret;
300+
301+
return count;
302+
}
275303
static ssize_t queue_nomerges_show(struct gendisk *disk, char *page)
276304
{
277305
return queue_var_show((blk_queue_nomerges(disk->queue) << 1) |
@@ -460,6 +488,7 @@ QUEUE_RO_ENTRY(queue_max_open_zones, "max_open_zones");
460488
QUEUE_RO_ENTRY(queue_max_active_zones, "max_active_zones");
461489

462490
QUEUE_RW_ENTRY(queue_nomerges, "nomerges");
491+
QUEUE_RW_ENTRY(queue_iostats_passthrough, "iostats_passthrough");
463492
QUEUE_RW_ENTRY(queue_rq_affinity, "rq_affinity");
464493
QUEUE_RW_ENTRY(queue_poll, "io_poll");
465494
QUEUE_RW_ENTRY(queue_poll_delay, "io_poll_delay");
@@ -586,6 +615,7 @@ static struct attribute *queue_attrs[] = {
586615
&queue_max_open_zones_entry.attr,
587616
&queue_max_active_zones_entry.attr,
588617
&queue_nomerges_entry.attr,
618+
&queue_iostats_passthrough_entry.attr,
589619
&queue_iostats_entry.attr,
590620
&queue_stable_writes_entry.attr,
591621
&queue_add_random_entry.attr,

include/linux/blkdev.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ typedef unsigned int __bitwise blk_flags_t;
349349
/* I/O topology is misaligned */
350350
#define BLK_FLAG_MISALIGNED ((__force blk_flags_t)(1u << 1))
351351

352+
/* passthrough command IO accounting */
353+
#define BLK_FLAG_IOSTATS_PASSTHROUGH ((__force blk_flags_t)(1u << 2))
354+
352355
struct queue_limits {
353356
blk_features_t features;
354357
blk_flags_t flags;
@@ -617,6 +620,8 @@ void blk_queue_flag_clear(unsigned int flag, struct request_queue *q);
617620
test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags)
618621
#define blk_queue_nonrot(q) (!((q)->limits.features & BLK_FEAT_ROTATIONAL))
619622
#define blk_queue_io_stat(q) ((q)->limits.features & BLK_FEAT_IO_STAT)
623+
#define blk_queue_passthrough_stat(q) \
624+
((q)->limits.flags & BLK_FLAG_IOSTATS_PASSTHROUGH)
620625
#define blk_queue_dax(q) ((q)->limits.features & BLK_FEAT_DAX)
621626
#define blk_queue_pci_p2pdma(q) ((q)->limits.features & BLK_FEAT_PCI_P2PDMA)
622627
#ifdef CONFIG_BLK_RQ_ALLOC_TIME

0 commit comments

Comments
 (0)