On 2022/05/23 19:06, Lianbo Jiang wrote: > 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, more complex... > 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 ffff8e99d0a1ae00 sda ffff8e9c14c59980 10 6 4 > > Signed-off-by: Lianbo Jiang <lijiang@xxxxxxxxxx> > --- > defs.h | 1 + > dev.c | 44 ++++++++++++++++++++++++++++++++++---------- > symbols.c | 2 ++ > 3 files changed, 37 insertions(+), 10 deletions(-) > > diff --git a/defs.h b/defs.h > index c1626bc79d59..1e435ffe5535 100644 > --- a/defs.h > +++ b/defs.h > @@ -2181,6 +2181,7 @@ struct offset_table { /* stash of commonly-used offsets */ > long blk_mq_tags_nr_reserved_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 7e0b3d27888d..811414d93c94 100644 > --- a/dev.c > +++ b/dev.c > @@ -4406,24 +4406,46 @@ static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio) > uint cnt = 0; > ulong addr = 0, hctx_addr = 0; > ulong *hctx_array = NULL; > + struct list_pair *lp = NULL; > struct diskio tmp = {0}; > > - addr = q + OFFSET(request_queue_nr_hw_queues); > - readmem(addr, KVADDR, &cnt, sizeof(uint), > - "request_queue.nr_hw_queues", FAULT_ON_ERROR); > + if (MEMBER_EXISTS("request_queue", "hctx_table")) { As MEMBER_OFFSET_INIT() was done, we can use VALID_MEMBER() macro, which is faster than MEMBER_EXISTS(), Thanks, Kazu > + 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); > + } else { > + addr = q + OFFSET(request_queue_nr_hw_queues); > + readmem(addr, KVADDR, &cnt, sizeof(uint), > + "request_queue.nr_hw_queues", FAULT_ON_ERROR); > > - addr = q + OFFSET(request_queue_queue_hw_ctx); > - readmem(addr, KVADDR, &hctx_addr, sizeof(void *), > - "request_queue.queue_hw_ctx", FAULT_ON_ERROR); > + addr = q + OFFSET(request_queue_queue_hw_ctx); > + readmem(addr, KVADDR, &hctx_addr, sizeof(void *), > + "request_queue.queue_hw_ctx", FAULT_ON_ERROR); > + } > > hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt); > - if (!hctx_array) > + if (!hctx_array) { > + if (lp) > + FREEBUF(lp); > error(FATAL, "fail to get memory for the hctx_array\n"); > + } > + > + if (lp && hctx_array) { > + uint i; > > - if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt, > + /* copy it from list_pair to hctx_array */ > + for (i = 0; i < cnt; i++) { > + hctx_array[i] = (ulong)lp[i].value; > + } > + FREEBUF(lp); > + } else if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt, > "request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) { > - FREEBUF(hctx_array); > - return; > + FREEBUF(hctx_array); > + return; > } > > queue_for_each_hw_ctx(q, hctx_array, cnt, &tmp); > @@ -4796,6 +4818,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 c432469671a4..cc439e8eb636 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", -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki