Please ignore the patch, filtering is incorrect. See "Add blk_mq
shared tags support for dev -d/-D" patch for the fix.

On Thu, Jun 26, 2025 at 12:16 PM Tao Liu <l...@redhat.com> wrote:
>
> CEE reported an issue that "dev -d/-D" reports incorrect value
> of read/write:
>
>     crash> dev -d
>     MAJOR GENDISK            NAME       REQUEST_QUEUE      TOTAL ASYNC  SYNC
>         8 ffff90528df86000   sda        ffff9052a3d61800     144   144     0
>         8 ffff905280718c00   sdb        ffff9052a3d63c00      48    48     0
>
>     crash> epython rqlist
>     ffff90528e94a5c0 sda      is unknown, deadline:  89.992 (90)  rq_alloc:   
> 0.196
>     ffff90528e92f700 sda      is unknown, deadline:  89.998 (90)  rq_alloc:   
> 0.202
>     ffff90528e95ccc0 sda      is unknown, deadline:  89.999 (90)  rq_alloc:   
> 0.203
>     ffff90528e968bc0 sdb      is unknown, deadline:  89.997 (90)  rq_alloc:   
> 0.201
>
> The value of 144 ASYNC is incorrect and epython rqlist only show 3 items for 
> sda.
> The reason is, mq_check_inflight() may get the same rq multiple times during
> iteration, so they are counted repeatly.
>
> This patch will add a rq repetition check. After apply the patch:
>
>     crash> dev -d
>     MAJOR GENDISK            NAME       REQUEST_QUEUE      TOTAL  READ WRITE
>         8 ffff90528df86000   sda        ffff9052a3d61800       3     3     0
>         8 ffff905280718c00   sdb        ffff9052a3d63c00       1     1     0
>
> Signed-off-by: Tao Liu <l...@redhat.com>
> ---
>  dev.c | 43 ++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 40 insertions(+), 3 deletions(-)
>
> diff --git a/dev.c b/dev.c
> index 9d38aef..b0434cf 100644
> --- a/dev.c
> +++ b/dev.c
> @@ -4316,6 +4316,9 @@ struct bt_iter_data {
>         ulong tags;
>         uint reserved;
>         uint nr_reserved_tags;
> +       ulong **rq_list;
> +       int *rq_list_len;
> +       int *rq_list_cap;
>         busy_tag_iter_fn *fn;
>         void *data;
>  };
> @@ -4381,10 +4384,30 @@ static bool bt_iter(uint bitnr, void *data)
>         if (!readmem(addr, KVADDR, &rq, sizeof(ulong), "blk_mq_tags.rqs[]", 
> RETURN_ON_ERROR))
>                 return FALSE;
>
> +       for (int i = 0; i < *iter_data->rq_list_len; i++) {
> +               /* Skip the handled rq */
> +               if ((*iter_data->rq_list)[i] == rq)
> +                       return TRUE;
> +       }
> +       /* Mark the rq is handled */
> +       (*iter_data->rq_list)[(*iter_data->rq_list_len)++] = rq;
> +       if (*iter_data->rq_list_len > *iter_data->rq_list_cap / 2) {
> +               *iter_data->rq_list_cap <<= 1;
> +               ulong *tmp = reallocarray(*iter_data->rq_list,
> +                                       *iter_data->rq_list_cap, 
> sizeof(ulong));
> +               if (!tmp) {
> +                       free(*iter_data->rq_list);
> +                       error(FATAL, "cannot reallocarray rq_list array");
> +               }
> +               *iter_data->rq_list = tmp;
> +       }
> +
>         return iter_data->fn(rq, iter_data->data);
>  }
>
> -static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint 
> nr_resvd_tags, struct diskio *dio)
> +static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved,
> +                       uint nr_resvd_tags, ulong **rq_list, int *rq_list_len,
> +                       int *rq_list_cap, struct diskio *dio)
>  {
>         struct sbitmap_context sc = {0};
>         struct mq_inflight mi = {
> @@ -4395,6 +4418,9 @@ static void bt_for_each(ulong q, ulong tags, ulong sbq, 
> uint reserved, uint nr_r
>                 .tags = tags,
>                 .reserved = reserved,
>                 .nr_reserved_tags = nr_resvd_tags,
> +               .rq_list = rq_list,
> +               .rq_list_len = rq_list_len,
> +               .rq_list_cap = rq_list_cap,
>                 .fn = mq_check_inflight,
>                 .data = &mi,
>         };
> @@ -4407,10 +4433,18 @@ static void queue_for_each_hw_ctx(ulong q, ulong 
> *hctx, uint cnt, struct diskio
>  {
>         uint i;
>         int bitmap_tags_is_ptr = 0;
> +       ulong *rq_list;
> +       int rq_list_len = 0;
> +       int rq_list_cap = 1;
>
>         if (MEMBER_TYPE("blk_mq_tags", "bitmap_tags") == TYPE_CODE_PTR)
>                 bitmap_tags_is_ptr = 1;
>
> +       rq_list = calloc(rq_list_cap, sizeof(ulong));
> +       if (!rq_list) {
> +               error(FATAL, "cannot malloc rq_list array");
> +       }
> +
>         for (i = 0; i < cnt; i++) {
>                 ulong addr = 0, tags = 0;
>                 uint nr_reserved_tags = 0;
> @@ -4432,15 +4466,18 @@ static void queue_for_each_hw_ctx(ulong q, ulong 
> *hctx, uint cnt, struct diskio
>                             !readmem(addr, KVADDR, &addr, sizeof(ulong),
>                                         "blk_mq_tags.bitmap_tags", 
> RETURN_ON_ERROR))
>                                 break;
> -                       bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
> +                       bt_for_each(q, tags, addr, 1, nr_reserved_tags, 
> &rq_list,
> +                                       &rq_list_len, &rq_list_cap, dio);
>                 }
>                 addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
>                 if (bitmap_tags_is_ptr &&
>                     !readmem(addr, KVADDR, &addr, sizeof(ulong),
>                                 "blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
>                         break;
> -               bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
> +               bt_for_each(q, tags, addr, 1, nr_reserved_tags, &rq_list,
> +                               &rq_list_len, &rq_list_cap, dio);
>         }
> +       free(rq_list);
>  }
>
>  static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
> --
> 2.47.0
>
--
Crash-utility mailing list -- devel@lists.crash-utility.osci.io
To unsubscribe send an email to devel-le...@lists.crash-utility.osci.io
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to