Kernel commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray") removed the "queue_hw_ctx" member from struct request_queue at Linux v5.18-rc1, and replaced it with a struct xarray "hctx_table".Without the patch, the "dev -d|-D" options will print an error: crash> dev -d MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE dev: invalid structure member offset: request_queue_queue_hw_ctx With the patch: crash> dev -d MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE 8 ffff892147e4ae00 sda ffff8922c891aa80 240 135 105 Signed-off-by: Lianbo Jiang <lijiang@xxxxxxxxxx> --- defs.h | 1 + dev.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ symbols.c | 2 ++ 3 files changed, 74 insertions(+) diff --git a/defs.h b/defs.h index f3c05fb44e62..fa49e9bdf767 100644 --- a/defs.h +++ b/defs.h @@ -2180,6 +2180,7 @@ struct offset_table { /* stash of commonly-used offsets */ long blk_mq_tags_nr_tags; long blk_mq_tags_rqs; long blk_mq_tags_static_rqs; + long request_queue_hctx_table; }; struct size_table { /* stash of commonly-used sizes */ diff --git a/dev.c b/dev.c index 4d574f06494f..64caaf4bd88d 100644 --- a/dev.c +++ b/dev.c @@ -4369,12 +4369,81 @@ sbitmap_word_buf_free: FREEBUF(sbitmap_word_buf); } +static void get_used_tags(unsigned long q, struct diskio *io_counts) +{ + unsigned long addr = 0; + unsigned long cnt = 0, i = 0; + struct list_pair *lp = NULL; + + addr = q + OFFSET(request_queue_hctx_table); + cnt = do_xarray(addr, XARRAY_COUNT, NULL); + lp = (struct list_pair *)GETBUF(sizeof(struct list_pair) * (cnt + 1)); + if (!lp) + error(FATAL, "fail to get memory for list_pair.\n"); + + lp[0].index = cnt; + cnt = do_xarray(addr, XARRAY_GATHER, lp); + for (i = 0; i < cnt; i++) { + ulong tags = 0, sched_tags = 0; + unsigned long *rqs = NULL, *static_rqs = NULL; + struct blk_mq_tags_context tags_ctx = {0}; + struct blk_mq_tags_context sched_tags_ctx = {0}; + + if(!IS_KVADDR((ulong)lp[i].value)) + continue; + + addr = (ulong)lp[i].value + OFFSET(blk_mq_hw_ctx_tags); + if (!readmem(addr, KVADDR, &tags, sizeof(ulong), + "blk_mq_hw_ctx.tags", RETURN_ON_ERROR)) + goto lp_free; + + addr = (ulong)lp[i].value + OFFSET(blk_mq_hw_ctx_sched_tags); + if (!readmem(addr, KVADDR, &sched_tags, sizeof(ulong), + "blk_mq_hw_ctx.sched_tags", RETURN_ON_ERROR)) + goto lp_free; + + if (IS_KVADDR(tags)) { + load_blk_mq_tags_context(tags, &tags_ctx); + load_blk_mq_rqs(tags_ctx.rqs, tags_ctx.nr_tags, &rqs); + if (!rqs) + goto next; + find_mq_diskio_by_parsing_bitmap(q, tags_ctx.breserved_tags, 0, rqs, &io_counts); + find_mq_diskio_by_parsing_bitmap(q, tags_ctx.bitmap_tags, tags_ctx.nr_reserved_tags, + rqs, &io_counts); + FREEBUF(rqs); + } + next: + if (IS_KVADDR(sched_tags)) { + load_blk_mq_tags_context(sched_tags, &sched_tags_ctx); + load_blk_mq_rqs(sched_tags_ctx.static_rqs, sched_tags_ctx.nr_tags, &static_rqs); + if (!static_rqs) + continue; + find_mq_diskio_by_parsing_bitmap(q, sched_tags_ctx.breserved_tags, 0, static_rqs, &io_counts); + find_mq_diskio_by_parsing_bitmap(q, sched_tags_ctx.bitmap_tags, sched_tags_ctx.nr_reserved_tags, + static_rqs, &io_counts); + FREEBUF(static_rqs); + } + } + +lp_free: + FREEBUF(lp); +} + static void get_mq_diskio_from_hw_queues(unsigned long q, struct diskio *io_counts) { unsigned long *queue_hw_ctx = NULL; unsigned long addr = 0; unsigned int i, nr_hw_queues; + if (MEMBER_EXISTS("request_queue", "hctx_table")) { + struct diskio tmp = {0}; + + get_used_tags(q, &tmp); + io_counts->read = tmp.read; + io_counts->write = tmp.write; + return; + } + addr = q + OFFSET(request_queue_nr_hw_queues); readmem(addr, KVADDR, &nr_hw_queues, sizeof(uint), "request_queue.nr_hw_queues", FAULT_ON_ERROR); @@ -4804,6 +4873,8 @@ void diskio_init(void) "request_queue", "queue_hw_ctx"); MEMBER_OFFSET_INIT(request_queue_nr_hw_queues, "request_queue", "nr_hw_queues"); + MEMBER_OFFSET_INIT(request_queue_hctx_table, + "request_queue", "hctx_table"); MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx", "rq_dispatched"); MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx", diff --git a/symbols.c b/symbols.c index 0612255b6e34..e1d8320c48bb 100644 --- a/symbols.c +++ b/symbols.c @@ -10401,6 +10401,8 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(request_queue_queue_hw_ctx)); fprintf(fp, " request_queue_nr_hw_queues: %ld\n", OFFSET(request_queue_nr_hw_queues)); + fprintf(fp, " request_queue_hctx_table: %ld\n", + OFFSET(request_queue_hctx_table)); fprintf(fp, " blk_mq_ctx_rq_dispatched: %ld\n", OFFSET(blk_mq_ctx_rq_dispatched)); fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n", -- 2.20.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki