<div dir="ltr"><div dir="ltr">On Wed, Jun 1, 2022 at 4:51 PM HAGIO KAZUHITO(萩尾 一仁) <<a href="mailto:k-hagio-ab@nec.com">k-hagio-ab@nec.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Lianbo,<br>
<br>
Thank you for the update, much better structure :)<br>
<br>
Let's go into detail...<br>
<br></blockquote><div><br></div><div>Thank you for helping the review, it seems that we are getting closer to this goal.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
On 2022/05/30 18:15, Lianbo Jiang wrote:<br>
> Currently, crash doesn't support to display disk I/O statistics<br>
> for blk-mq devices. For more details, please refer to the following<br>
> commit: <98b417fc6346> ("Handle blk_mq_ctx member changes for kernels<br>
> 5.16-rc1 and later").<br>
> <br>
> Lets parse the bitmap in blk-mq layer to achieve it.<br>
> <br>
> Signed-off-by: Lianbo Jiang <<a href="mailto:lijiang@redhat.com" target="_blank">lijiang@redhat.com</a>><br>
> ---<br>
> defs.h | 11 +++<br>
> dev.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++--------<br>
> symbols.c | 22 +++++<br>
> 3 files changed, 255 insertions(+), 39 deletions(-)<br>
> <br>
> diff --git a/defs.h b/defs.h<br>
> index c8444b4e54eb..2681586a33dc 100644<br>
> --- a/defs.h<br>
> +++ b/defs.h<br>
> @@ -2170,6 +2170,16 @@ struct offset_table { /* stash of commonly-used offsets */<br>
> long sbq_wait_state_wait;<br>
> long sbitmap_alloc_hint;<br>
> long sbitmap_round_robin;<br>
> + long request_cmd_flags;<br>
> + long request_q;<br>
> + long request_state;<br>
> + long request_queue_queue_hw_ctx;<br>
> + long request_queue_nr_hw_queues;<br>
> + long blk_mq_hw_ctx_tags;<br>
> + long blk_mq_tags_bitmap_tags;<br>
> + long blk_mq_tags_breserved_tags;<br>
> + long blk_mq_tags_nr_reserved_tags;<br>
> + long blk_mq_tags_rqs;<br>
> };<br>
> <br>
> struct size_table { /* stash of commonly-used sizes */<br>
> @@ -2339,6 +2349,7 @@ struct size_table { /* stash of commonly-used sizes */<br>
> long sbitmap;<br>
> long sbitmap_queue;<br>
> long sbq_wait_state;<br>
> + long blk_mq_tags;<br>
> };<br>
> <br>
> struct array_table {<br>
> diff --git a/dev.c b/dev.c<br>
> index a493e51ac95c..c0240f7b889b 100644<br>
> --- a/dev.c<br>
> +++ b/dev.c<br>
> @@ -4238,19 +4238,193 @@ get_one_mctx_diskio(unsigned long mctx, struct diskio *io)<br>
> io->write = (dispatch[1] - comp[1]);<br>
> }<br>
> <br>
> +typedef bool (busy_tag_iter_fn)(ulong rq, void *data);<br>
> +<br>
> +struct bt_iter_data {<br>
<br>
I think that some names are confusing and not synced with the kernel.<br>
How about renaming to "mq_inflight"?<br>
<br>
> + ulong q;<br>
> + struct diskio *dio;<br>
> +};<br>
> +<br>
> +struct bt_tags_iter_data {<br>
<br>
And please rename this to "bt_iter_data".<br>
<br>
> + ulong tags;<br>
> + uint flags;<br>
<br>
rename to "reserved".<br>
<br></blockquote><div><br></div><div>OK, I will rename the above three variables.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> + uint nr_reserved_tags;<br>
> + busy_tag_iter_fn *fn;<br>
> + void *data;<br>
> +};<br>
> +<br>
> +/*<br>
> + * See the include/linux/blk_types.h and include/linux/blk-mq.h<br>
> + */<br>
> +#define MQ_RQ_IN_FLIGHT 1<br>
> +#define REQ_OP_BITS 8<br>
> +#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)<br>
> +<br>
> +static uint op_is_write(uint op)<br>
> +{<br>
> + return (op & REQ_OP_MASK) & 1;<br>
> +}<br>
> +<br>
> +static bool mq_check_inflight(ulong rq, void *data)<br>
> +{<br>
> + uint cmd_flags = 0, state = 0;<br>
> + ulong addr = 0, queue = 0;<br>
> + struct bt_iter_data *iter = data;<br>
> +<br>
> + if (!IS_KVADDR(rq))<br>
> + return TRUE;<br>
<br>
Why return TRUE?<br>
Does this mean that rq can be invalid with bit on?<br></blockquote><div> </div><div>The intent is to filter out the zero address of rq, and crash cannot completely believe that the address</div><div>of rq is always valid. To be on the safe side, it should be good to do this check.</div><div>In addition, the kernel has the similar logic of code, for example:</div><div>static bool bt_tags_iter(...)</div><div>{</div><div>...</div><div>if (!rq)<br> return true;</div><div> ^^^^<br></div><div>...<br></div><div>}<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> +<br>
> + addr = rq + OFFSET(request_q);<br>
> + if (!readmem(addr, KVADDR, &queue, sizeof(ulong), "request.q", RETURN_ON_ERROR))<br>
> + return FALSE;<br>
> +<br>
> + addr = rq + OFFSET(request_cmd_flags);<br>
> + if (!readmem(addr, KVADDR, &cmd_flags, sizeof(uint), "request.cmd_flags", RETURN_ON_ERROR))<br>
> + return FALSE;<br>
> +<br>
> + addr = rq + OFFSET(request_state);<br>
> + if (!readmem(addr, KVADDR, &state, sizeof(uint), "request.state", RETURN_ON_ERROR))<br>
> + return FALSE;<br>
<br>
Rethinking these, RETURN_ON_ERROR leads to stop counting (i.e. wrong results)<br>
with error messages. I think it would be better to use FAULT_ON_ERROR unless<br>
we can ignore or handle an error correctly. What do you think?<br>
<br>
(And for the RETURN_ON_ERRORs below, same as above.)<br>
<br></blockquote><div>At first, I had the same opinion as yours. But eventually, called the readmem() with the "RETURN_ON_ERROR",</div><div>the reason is that crash can help to output the statistics as much as possible, which is helpful to user, and once the</div><div> readmem() failed, it will print an appropriate error, and it can explicitly tell users that the statistics may be unreliable.<br></div><div><br></div><div>If this is really confusing to the user, let's replace it with the "FAULT_ON_ERROR".</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> +<br>
> + if (queue == iter->q && state == MQ_RQ_IN_FLIGHT) {<br>
> + if (op_is_write(cmd_flags))<br>
> + iter->dio->write++;<br>
> + else<br>
> + iter->dio->read++;<br>
> + }<br>
> +<br>
> + return TRUE;<br>
> +}<br>
> +<br>
> +static bool bt_tags_iter(uint bitnr, void *data)<br>
> +{<br>
> + ulong addr = 0, rqs_addr = 0, rq = 0;<br>
> + struct bt_tags_iter_data *tag_iter = data;<br>
> + ulong tag = tag_iter->tags;<br>
> +<br>
> + if (!tag_iter->flags)<br>
> + bitnr += tag_iter->nr_reserved_tags;<br>
> +<br>
> + /* rqs */<br>
> + addr = tag + OFFSET(blk_mq_tags_rqs);<br>
> + if (!readmem(addr, KVADDR, &rqs_addr, sizeof(void *), "blk_mq_tags.rqs", RETURN_ON_ERROR))<br>
> + return FALSE;<br>
> +<br>
> + addr = rqs_addr + bitnr * sizeof(ulong); /* rqs[bitnr] */<br>
> + if (!readmem(addr, KVADDR, &rq, sizeof(ulong), "blk_mq_tags.rqs[]", RETURN_ON_ERROR))<br>
> + return FALSE;<br>
> +<br>
> + return tag_iter->fn(rq, tag_iter->data);<br>
> +}<br>
> +<br>
> +static void bt_tags_for_each(ulong q, ulong tags, ulong sbq, uint flags, uint nr_resvd_tags, struct diskio *dio)<br>
<br>
Please rename this to bt_for_each.<br>
<br></blockquote><div> </div>No problem.<br></div><div class="gmail_quote"><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
> +{<br>
> + struct sbitmap_context sc = {0};<br>
<br>
> + struct diskio tmp = {0};<br>
<br>
This tmp can be removed?<br>
<br>
(The dio->{read,write} are incremented in mq_check_inflight(), so<br>
we don't need the local tmps for each function, I think)<br>
<br></div></blockquote><div>Let me double check.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
> + struct bt_iter_data iter_data = {<br>
> + .q = q,<br>
> + .dio = &tmp,<br>
> + };<br>
> + struct bt_tags_iter_data tags_iter_data = {<br>
> + .tags = tags,<br>
> + .flags = flags,<br>
> + .nr_reserved_tags = nr_resvd_tags,<br>
> + .fn = mq_check_inflight,<br>
> + .data = &iter_data,<br>
> + };<br>
> +<br>
> + sbitmap_context_load(sbq + OFFSET(sbitmap_queue_sb), &sc);<br>
> + sbitmap_for_each_set(&sc, bt_tags_iter, &tags_iter_data);<br>
> +<br>
> + dio->read = tmp.read;<br>
> + dio->write = tmp.write;<br>
> +}<br>
> +<br>
> +static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)<br>
> +{<br>
> + uint i;<br>
<br>
> + struct diskio tmp = {0};<br>
<br>
This also can be removed.<br>
<br>
> +<br>
> + if (!hctx || !dio)<br>
> + error(FATAL, "%s: Invalid parameter.\n", __func__);<br>
<br>
This can be used?<br>
<br></div></blockquote><div>Will remove it.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
> +<br>
> + for (i = 0; i < cnt; i++) {<br>
> + ulong addr = 0, tags = 0;<br>
> + uint nr_reserved_tags = 0;<br>
> +<br>
<br>
> + if (!IS_KVADDR(hctx[i]))<br>
> + continue;<br>
<br></div>
Is this the remain of the v1 patch?</blockquote><div><br></div><div>Yes, this can be removed from the 'for loop'. <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> +<br>
> + /* Tags owned by the block driver */<br>
> + addr = hctx[i] + OFFSET(blk_mq_hw_ctx_tags);<br>
> + if (!readmem(addr, KVADDR, &tags, sizeof(ulong),<br>
> + "blk_mq_hw_ctx.tags", RETURN_ON_ERROR))<br>
> + break;<br>
> +<br>
> + addr = tags + OFFSET(blk_mq_tags_nr_reserved_tags);<br>
> + if (!readmem(addr, KVADDR, &nr_reserved_tags, sizeof(uint),<br>
> + "blk_mq_tags_nr_reserved_tags", RETURN_ON_ERROR))<br>
> + break;<br>
> +<br>
> + if (nr_reserved_tags) {<br>
> + addr = tags + OFFSET(blk_mq_tags_breserved_tags);<br>
> + bt_tags_for_each(q, tags, addr, 1, nr_reserved_tags, &tmp);<br>
> + }<br>
> + addr = tags + OFFSET(blk_mq_tags_bitmap_tags);<br>
> + bt_tags_for_each(q, tags, addr, 0, nr_reserved_tags, &tmp);<br>
<br>
(the local tmp set by the nr_reserved_tags case is overwritten here.)<br></blockquote><div> </div><div>Thanks for pointing out this issue. It should be accumulated in the bt_tags_for_each() as below:</div><div>+ dio->read += tmp.read;<br>+ dio->write += tmp.write;</div><div><br></div><div>But anyway, I will rethink the variable 'tmp' and see what is the good way.<br></div><div><br></div><div>Thanks.</div><div>Lianbo<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> + }<br>
> +<br>
> + dio->read = tmp.read;<br>
> + dio->write = tmp.write;<br>
> +}<br>
> +<br>
> +static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)<br>
> +{<br>
> + uint cnt = 0;<br>
> + ulong addr = 0, hctx_addr = 0;<br>
> + ulong *hctx_array = NULL;<br>
<br>
> + struct diskio tmp = {0};<br>
<br>
This also can be removed.<br>
<br></blockquote><div>Ditto.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> +<br>
> + addr = q + OFFSET(request_queue_nr_hw_queues);<br>
> + readmem(addr, KVADDR, &cnt, sizeof(uint),<br>
> + "request_queue.nr_hw_queues", FAULT_ON_ERROR);<br>
> +<br>
> + addr = q + OFFSET(request_queue_queue_hw_ctx);<br>
> + readmem(addr, KVADDR, &hctx_addr, sizeof(void *),<br>
> + "request_queue.queue_hw_ctx", FAULT_ON_ERROR);<br>
> +<br>
> + hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt);<br>
> + if (!hctx_array)<br>
> + error(FATAL, "fail to get memory for the hctx_array\n");<br>
> +<br>
> + if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,<br>
> + "request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) {<br>
> + FREEBUF(hctx_array);<br>
> + return;<br>
> + }<br>
> +<br>
> + queue_for_each_hw_ctx(q, hctx_array, cnt, &tmp);<br>
> + dio->read = tmp.read;<br>
> + dio->write = tmp.write;<br>
> +<br>
> + FREEBUF(hctx_array);<br>
> +}<br>
> +<br>
> static void<br>
> get_mq_diskio(unsigned long q, unsigned long *mq_count)<br>
> {<br>
> int cpu;<br>
> unsigned long queue_ctx;<br>
> unsigned long mctx_addr;<br>
> - struct diskio tmp;<br>
> + struct diskio tmp = {0};<br>
> <br>
> if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||<br>
> - INVALID_MEMBER(blk_mq_ctx_rq_completed))<br>
> + INVALID_MEMBER(blk_mq_ctx_rq_completed)) {<br>
> + get_mq_diskio_from_hw_queues(q, &tmp);<br>
> + mq_count[0] = tmp.read;<br>
> + mq_count[1] = tmp.write;<br>
> return;<br>
> -<br>
> - memset(&tmp, 0x00, sizeof(struct diskio));<br>
> + }<br>
> <br>
> readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,<br>
> sizeof(ulong), "request_queue.queue_ctx",<br>
> @@ -4479,41 +4653,24 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)<br>
> && (io.read + io.write == 0))<br>
> return;<br>
> <br>
> - if (use_mq_interface(queue_addr) &&<br>
> - (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||<br>
> - INVALID_MEMBER(blk_mq_ctx_rq_completed)))<br>
> - fprintf(fp, "%s%s%s %s%s%s%s %s%s%s",<br>
> - mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),<br>
> - space(MINSPACE),<br>
> - mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),<br>
> - space(MINSPACE),<br>
> - mkstring(buf2, 10, LJUST, disk_name),<br>
> - space(MINSPACE),<br>
> - mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,<br>
> - LJUST|LONG_HEX, (char *)queue_addr),<br>
> - space(MINSPACE),<br>
> - mkstring(buf4, 17, RJUST, "(not supported)"),<br>
> - space(MINSPACE));<br>
> -<br>
> - else<br>
> - fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",<br>
> - mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),<br>
> - space(MINSPACE),<br>
> - mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),<br>
> - space(MINSPACE),<br>
> - mkstring(buf2, 10, LJUST, disk_name),<br>
> - space(MINSPACE),<br>
> - mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,<br>
> - LJUST|LONG_HEX, (char *)queue_addr),<br>
> - space(MINSPACE),<br>
> - io.read + io.write,<br>
> - space(MINSPACE),<br>
> - mkstring(buf4, 5, RJUST|INT_DEC,<br>
> - (char *)(unsigned long)io.read),<br>
> - space(MINSPACE),<br>
> - mkstring(buf5, 5, RJUST|INT_DEC,<br>
> - (char *)(unsigned long)io.write),<br>
> - space(MINSPACE));<br>
> + fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",<br>
> + mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),<br>
> + space(MINSPACE),<br>
> + mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),<br>
> + space(MINSPACE),<br>
> + mkstring(buf2, 10, LJUST, disk_name),<br>
> + space(MINSPACE),<br>
> + mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,<br>
> + LJUST|LONG_HEX, (char *)queue_addr),<br>
> + space(MINSPACE),<br>
> + io.read + io.write,<br>
> + space(MINSPACE),<br>
> + mkstring(buf4, 5, RJUST|INT_DEC,<br>
> + (char *)(unsigned long)io.read),<br>
> + space(MINSPACE),<br>
> + mkstring(buf5, 5, RJUST|INT_DEC,<br>
> + (char *)(unsigned long)io.write),<br>
> + space(MINSPACE));<br>
> <br>
> if (VALID_MEMBER(request_queue_in_flight)) {<br>
> if (!use_mq_interface(queue_addr)) {<br>
> @@ -4597,6 +4754,9 @@ void diskio_init(void)<br>
> MEMBER_OFFSET_INIT(kobject_entry, "kobject", "entry");<br>
> MEMBER_OFFSET_INIT(kset_list, "kset", "list");<br>
> MEMBER_OFFSET_INIT(request_list_count, "request_list", "count");<br>
> + MEMBER_OFFSET_INIT(request_cmd_flags, "request", "cmd_flags");<br>
> + MEMBER_OFFSET_INIT(request_q, "request", "q");<br>
> + MEMBER_OFFSET_INIT(request_state, "request", "state");<br>
> MEMBER_OFFSET_INIT(request_queue_in_flight, "request_queue",<br>
> "in_flight");<br>
> if (MEMBER_EXISTS("request_queue", "rq"))<br>
> @@ -4608,10 +4768,33 @@ void diskio_init(void)<br>
> "mq_ops");<br>
> ANON_MEMBER_OFFSET_INIT(request_queue_queue_ctx,<br>
> "request_queue", "queue_ctx");<br>
> + MEMBER_OFFSET_INIT(request_queue_queue_hw_ctx,<br>
> + "request_queue", "queue_hw_ctx");<br>
> + MEMBER_OFFSET_INIT(request_queue_nr_hw_queues,<br>
> + "request_queue", "nr_hw_queues");<br>
> MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",<br>
> "rq_dispatched");<br>
> MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",<br>
> "rq_completed");<br>
> + MEMBER_OFFSET_INIT(blk_mq_hw_ctx_tags, "blk_mq_hw_ctx", "tags");<br>
> + MEMBER_OFFSET_INIT(blk_mq_tags_bitmap_tags, "blk_mq_tags",<br>
> + "bitmap_tags");<br>
> + MEMBER_OFFSET_INIT(blk_mq_tags_breserved_tags, "blk_mq_tags",<br>
> + "breserved_tags");<br>
> + MEMBER_OFFSET_INIT(blk_mq_tags_nr_reserved_tags, "blk_mq_tags",<br>
> + "nr_reserved_tags");<br>
> + MEMBER_OFFSET_INIT(blk_mq_tags_rqs, "blk_mq_tags", "rqs");<br>
> + STRUCT_SIZE_INIT(blk_mq_tags, "blk_mq_tags");<br>
> + STRUCT_SIZE_INIT(sbitmap, "sbitmap");<br>
> + STRUCT_SIZE_INIT(sbitmap_word, "sbitmap_word");<br>
> + MEMBER_OFFSET_INIT(sbitmap_word_word, "sbitmap_word", "word");<br>
> + MEMBER_OFFSET_INIT(sbitmap_word_cleared, "sbitmap_word", "cleared");<br>
> + MEMBER_OFFSET_INIT(sbitmap_depth, "sbitmap", "depth");<br>
> + MEMBER_OFFSET_INIT(sbitmap_shift, "sbitmap", "shift");<br>
> + MEMBER_OFFSET_INIT(sbitmap_map_nr, "sbitmap", "map_nr");<br>
> + MEMBER_OFFSET_INIT(sbitmap_map, "sbitmap", "map");<br>
> + MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");<br>
> +<br>
> }<br>
> MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",<br>
> "klist_devices");<br>
> diff --git a/symbols.c b/symbols.c<br>
> index 5d12a021c769..c1f09556d710 100644<br>
> --- a/symbols.c<br>
> +++ b/symbols.c<br>
> @@ -10385,6 +10385,12 @@ dump_offset_table(char *spec, ulong makestruct)<br>
> OFFSET(kset_list));<br>
> fprintf(fp, " request_list_count: %ld\n",<br>
> OFFSET(request_list_count));<br>
> + fprintf(fp, " request_cmd_flags: %ld\n",<br>
> + OFFSET(request_cmd_flags));<br>
> + fprintf(fp, " request_q: %ld\n",<br>
> + OFFSET(request_q));<br>
> + fprintf(fp, " request_state: %ld\n",<br>
> + OFFSET(request_state));<br>
> fprintf(fp, " request_queue_in_flight: %ld\n",<br>
> OFFSET(request_queue_in_flight));<br>
> fprintf(fp, " request_queue_rq: %ld\n",<br>
> @@ -10393,10 +10399,25 @@ dump_offset_table(char *spec, ulong makestruct)<br>
> OFFSET(request_queue_mq_ops));<br>
> fprintf(fp, " request_queue_queue_ctx: %ld\n",<br>
> OFFSET(request_queue_queue_ctx));<br>
> + fprintf(fp, " request_queue_queue_hw_ctx: %ld\n",<br>
> + OFFSET(request_queue_queue_hw_ctx));<br>
> + fprintf(fp, " request_queue_nr_hw_queues: %ld\n",<br>
> + OFFSET(request_queue_nr_hw_queues));<br>
> fprintf(fp, " blk_mq_ctx_rq_dispatched: %ld\n",<br>
> OFFSET(blk_mq_ctx_rq_dispatched));<br>
> fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",<br>
> OFFSET(blk_mq_ctx_rq_completed));<br>
> + fprintf(fp, " blk_mq_hw_ctx_tags: %ld\n",<br>
> + OFFSET(blk_mq_hw_ctx_tags));<br>
> + fprintf(fp, " blk_mq_tags_bitmap_tags: %ld\n",<br>
> + OFFSET(blk_mq_tags_bitmap_tags));<br>
> + fprintf(fp, " blk_mq_tags_breserved_tags: %ld\n",<br>
> + OFFSET(blk_mq_tags_breserved_tags));<br>
> + fprintf(fp, " blk_mq_tags_nr_reserved_tags: %ld\n",<br>
> + OFFSET(blk_mq_tags_nr_reserved_tags));<br>
> + fprintf(fp, " blk_mq_tags_rqs: %ld\n",<br>
> + OFFSET(blk_mq_tags_rqs));<br>
<br>
Good, thanks for adjusting these indents.<br>
<br>
Thanks,<br>
Kazu<br>
<br>
> +<br>
> fprintf(fp, " subsys_private_klist_devices: %ld\n",<br>
> OFFSET(subsys_private_klist_devices));<br>
> fprintf(fp, " subsystem_kset: %ld\n",<br>
> @@ -11003,6 +11024,7 @@ dump_offset_table(char *spec, ulong makestruct)<br>
> fprintf(fp, " sbitmap: %ld\n", SIZE(sbitmap));<br>
> fprintf(fp, " sbitmap_queue: %ld\n", SIZE(sbitmap_queue));<br>
> fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));<br>
> + fprintf(fp, " blk_mq_tags: %ld\n", SIZE(blk_mq_tags));<br>
> <br>
> fprintf(fp, "\n array_table:\n");<br>
> /*</blockquote></div></div>