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(a)redhat.com>
---
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