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".

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.miz...@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@redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
> 

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to