[Crash-utility] [PATCH] dev: improvement for displaying I/O statics for blk-mq disk
Masayoshi Mizuma
m.mizuma at jp.fujitsu.com
Thu Oct 13 05:46:49 UTC 2016
Hi Dave,
On Wed, 12 Oct 2016 11:32:57 -0400 Dave Anderson wrote:
>
> Hello Masayoshi,
>
> I moved the new offset_table entries to the end of the structure to
> prevent any pre-existing extension modules from breaking, and I added
> their offsets to the dump_offset_table() function for "help -o".
Thank you for the additional changes!
- Masayoshi Mizuma
>
> Queued for crash-7.1.6:
>
> https://github.com/crash-utility/crash/commit/df08978f31ba39e94b3096804f4e0776373c8b53
>
> Thanks,
> Dave
>
>
> ----- Original Message -----
>> Improvement -d option of dev command to display I/O statics
>> for the disk which the device driver uses blk-mq interface.
>>
>> Current dev -d displays always 0 in the all fields for the
>> blk-mq disk because blk-mq does not increment/decrement to
>> request_list.count[2] on I/O creation and I/O completion.
>>
>> The following value is used in blk-mq on such situation.
>>
>> - I/O creation: blk_mq_ctx.rq_dispatched[2]
>> - I/O completion: blk_mq_ctx.rq_completed[2]
>>
>> So, we can get the counter of in progress I/Os as follows.
>>
>> in progress I/Os == rq_dispatched - rq_completed
>>
>> This patch displays the result of above calculation for the
>> disk. It judges as the device driver uses blk-mq if the
>> request_queue.mq_ops is not NULL.
>>
>> "DRV" field is displayed as "N/A(MQ)" because the value for in-flight
>> in the device driver is not exists for blk-mq...
>>
>> Signed-off-by: Masayoshi Mizuma <m.mizuma at jp.fujitsu.com>
>> ---
>> defs.h | 4 +++
>> dev.c | 98
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
>> help.c | 4 ++-
>> 3 files changed, 96 insertions(+), 10 deletions(-)
>>
>> diff --git a/defs.h b/defs.h
>> index a09fa9a..55c28c5 100755
>> --- a/defs.h
>> +++ b/defs.h
>> @@ -1822,6 +1822,10 @@ struct offset_table { /* stash of
>> commonly-used offsets */
>> long request_list_count;
>> long request_queue_in_flight;
>> long request_queue_rq;
>> + long request_queue_mq_ops;
>> + long request_queue_queue_ctx;
>> + long blk_mq_ctx_rq_dispatched;
>> + long blk_mq_ctx_rq_completed;
>> long subsys_private_klist_devices;
>> long subsystem_kset;
>> long mount_mnt_parent;
>> diff --git a/dev.c b/dev.c
>> index c18f40e..e46081e 100644
>> --- a/dev.c
>> +++ b/dev.c
>> @@ -3800,18 +3800,84 @@ again:
>> return i->get_gendisk(klist_node_address);
>> }
>>
>> +static int
>> +use_mq_interface(unsigned long q)
>> +{
>> + unsigned long mq_ops;
>> +
>> + if (!VALID_MEMBER(request_queue_mq_ops))
>> + return 0;
>> +
>> + readmem(q + OFFSET(request_queue_mq_ops), KVADDR, &mq_ops,
>> + sizeof(ulong), "request_queue.mq_ops", FAULT_ON_ERROR);
>> +
>> + if (mq_ops == 0)
>> + return 0;
>> + else
>> + return 1;
>> +}
>> +
>> +static void
>> +get_one_mctx_diskio(unsigned long mctx, struct diskio *io)
>> +{
>> + unsigned long dispatch[2];
>> + unsigned long comp[2];
>> +
>> + readmem(mctx + OFFSET(blk_mq_ctx_rq_dispatched),
>> + KVADDR, dispatch, sizeof(ulong) * 2, "blk_mq_ctx.rq_dispatched",
>> + FAULT_ON_ERROR);
>> +
>> + readmem(mctx + OFFSET(blk_mq_ctx_rq_completed),
>> + KVADDR, comp, sizeof(ulong) * 2, "blk_mq_ctx.rq_completed",
>> + FAULT_ON_ERROR);
>> +
>> + io->read = (dispatch[0] - comp[0]);
>> + io->write = (dispatch[1] - comp[1]);
>> +}
>> +
>> +static void
>> +get_mq_diskio(unsigned long q, unsigned long *mq_count)
>> +{
>> + int cpu;
>> + unsigned long queue_ctx;
>> + unsigned long mctx_addr;
>> + struct diskio tmp;
>> +
>> + memset(&tmp, 0x00, sizeof(struct diskio));
>> +
>> + readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
>> + sizeof(ulong), "request_queue.queue_ctx",
>> + FAULT_ON_ERROR);
>> +
>> + for (cpu = 0; cpu < kt->cpus; cpu++) {
>> + if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
>> + mctx_addr = queue_ctx + kt->__per_cpu_offset[cpu];
>> + get_one_mctx_diskio(mctx_addr, &tmp);
>> + mq_count[0] += tmp.read;
>> + mq_count[1] += tmp.write;
>> + }
>> + }
>> +}
>> +
>> /* read request_queue.rq.count[2] */
>> static void
>> get_diskio_1(unsigned long rq, struct diskio *io)
>> {
>> int count[2];
>> + unsigned long mq_count[2] = { 0 };
>>
>> - readmem(rq + OFFSET(request_queue_rq) + OFFSET(request_list_count),
>> - KVADDR, count, sizeof(int) * 2, "request_list.count",
>> - FAULT_ON_ERROR);
>> + if (!use_mq_interface(rq)) {
>> + readmem(rq + OFFSET(request_queue_rq) +
>> + OFFSET(request_list_count), KVADDR, count,
>> + sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
>>
>> - io->read = count[0];
>> - io->write = count[1];
>> + io->read = count[0];
>> + io->write = count[1];
>> + } else {
>> + get_mq_diskio(rq, mq_count);
>> + io->read = mq_count[0];
>> + io->write = mq_count[1];
>> + }
>> }
>>
>> /* request_queue.in_flight contains total requests */
>> @@ -3961,9 +4027,8 @@ display_one_diskio(struct iter *i, unsigned long
>> gendisk)
>> readmem(gendisk + OFFSET(gendisk_major), KVADDR, &major, sizeof(int),
>> "gen_disk.major", FAULT_ON_ERROR);
>> i->get_diskio(queue_addr, &io);
>> - in_flight = i->get_in_flight(queue_addr);
>>
>> - fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s%5u\n",
>> + fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
>> mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
>> space(MINSPACE),
>> mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
>> @@ -3980,8 +4045,13 @@ display_one_diskio(struct iter *i, unsigned long
>> gendisk)
>> space(MINSPACE),
>> mkstring(buf5, 5, RJUST|INT_DEC,
>> (char *)(unsigned long)io.write),
>> - space(MINSPACE),
>> - in_flight);
>> + space(MINSPACE));
>> +
>> + if (!use_mq_interface(queue_addr)) {
>> + in_flight = i->get_in_flight(queue_addr);
>> + fprintf(fp, "%5u\n", in_flight);
>> + } else
>> + fprintf(fp, "%s\n", "N/A(MQ)");
>> }
>>
>> static void
>> @@ -4056,6 +4126,16 @@ void diskio_init(void)
>> MEMBER_OFFSET_INIT(request_queue_rq, "request_queue", "rq");
>> else
>> MEMBER_OFFSET_INIT(request_queue_rq, "request_queue", "root_rl");
>> + if (MEMBER_EXISTS("request_queue", "mq_ops")) {
>> + MEMBER_OFFSET_INIT(request_queue_mq_ops, "request_queue",
>> + "mq_ops");
>> + ANON_MEMBER_OFFSET_INIT(request_queue_queue_ctx,
>> + "request_queue", "queue_ctx");
>> + MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
>> + "rq_dispatched");
>> + MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
>> + "rq_completed");
>> + }
>> MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",
>> "klist_devices");
>> MEMBER_OFFSET_INIT(subsystem_kset, "subsystem", "kset");
>> diff --git a/help.c b/help.c
>> index 938251f..cfa0516 100644
>> --- a/help.c
>> +++ b/help.c
>> @@ -2684,7 +2684,9 @@ char *help_dev[] = {
>> " ASYNC: I/O requests that are asynchronous",
>> " READ: I/O requests that are reads (older kernels)",
>> " WRITE: I/O requests that are writes (older kernels)",
>> -" DRV: I/O requests that are in-flight in the device driver",
>> +" DRV: I/O requests that are in-flight in the device driver.",
>> +" If the device driver uses blk-mq interface, this field",
>> +" shows N/A(MQ).",
>> "\nEXAMPLES",
>> " Display character and block device data:\n",
>> " %s> dev",
>> --
>> 1.8.3.1
>>
>> --
>> Crash-utility mailing list
>> Crash-utility at redhat.com
>> https://www.redhat.com/mailman/listinfo/crash-utility
>>
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
>
More information about the Crash-utility
mailing list