[PATCH 2/2] block: hold queue lock while iterating in diskstats_show

From: Daniel Wagner
Date: Thu Jan 20 2022 - 05:53:19 EST


The request queues can be freed while we operate on them. Make sure we
hold a reference when using blk_mq_queue_tag_busy_iter.

RIP: blk_mq_queue_tag_busy_iter
Call Trace:
? blk_mq_hctx_mark_pending
? diskstats_show
? blk_mq_hctx_mark_pending
blk_mq_in_flight
diskstats_show
? klist_next
seq_read
proc_reg_read
vfs_read
ksys_read
do_syscall_64
entry_SYSCALL_64_after_hwframe

Signed-off-by: Daniel Wagner <dwagner@xxxxxxx>
---
block/genhd.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/block/genhd.c b/block/genhd.c
index c9d4386dd177..0e163055a4e6 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1167,10 +1167,13 @@ static int diskstats_show(struct seq_file *seqf, void *v)
if (bdev_is_partition(hd) && !bdev_nr_sectors(hd))
continue;
part_stat_read_all(hd, &stat);
+ if (blk_queue_enter(gp->queue, BLK_MQ_REQ_NOWAIT))
+ continue;
if (queue_is_mq(gp->queue))
inflight = blk_mq_in_flight(gp->queue, hd);
else
inflight = part_in_flight(hd);
+ blk_queue_exit(gp->queue);

seq_printf(seqf, "%4d %7d %pg "
"%lu %lu %lu %u "
--
2.29.2