----- Original Message -----
> On 8/1/2019 2:31 PM, Kazuhito Hagio wrote:
> > On 8/1/2019 1:22 PM, Dave Anderson wrote:
> >>
> >>
> >> ----- Original Message -----
> >>> Hi Dave,
> >>>
> >>> I noticed that the "timer" command prints somewhat wrongly for RHEL7.6 or
> >>> later kernels (not including RHEL8 / upstream) and found that it is
> >>> because
> >>> struct tvec and tvec_root have an array of list_head, instead of
> >>> hlist_head
> >>> in upstream kernels.
> >>>
> >>> So the following patch looks good only for RHEL7, but I don't know how we
> >>> should determine the list type in order to switch the size, etc in this 
> >>> case.
> >>> What do you think?
> >>
> >> Try using the MEMBER_TYPE_NAME() macro.  For example, adding this to
> >> cmd_test():
> > 
> > Nice. I'll try to rewrite the patch with it.
> 
> I choose to add head_size arg to do_timer_list_v3().
> This tested OK on RHEL7.6 and kernel 4.2.1.

Thanks Kazu, it looks good -- queued for crash-7.2.7:

  
https://github.com/crash-utility/crash/commit/a812e59a175c8c6197ae3dc78bd5e1613adcc57c

Dave

  
> 
> Signed-off-by: Kazuhito Hagio <[email protected]>
> ---
> diff --git a/kernel.c b/kernel.c
> index a79e5a3010ea..7804aef2074b 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -53,7 +53,7 @@ static void dump_timer_data_timer_bases(const ulong *cpus);
>  struct tv_range;
>  static void init_tv_ranges(struct tv_range *, int, int, int);
>  static int do_timer_list(ulong,int, ulong *, void *,ulong *, ulong *, struct
>  tv_range *, ulong);
> -static int do_timer_list_v3(ulong, int, ulong *, void *,ulong *, ulong *,
> ulong);
> +static int do_timer_list_v3(ulong, int, ulong *, void *,ulong *, ulong *,
> ulong, long);
>  struct timer_bases_data;
>  static int do_timer_list_v4(struct timer_bases_data *, ulong);
>  static int compare_timer_data(const void *, const void *);
> @@ -8376,7 +8376,12 @@ dump_timer_data_tvec_bases_v3(const ulong *cpus)
>       char buf4[BUFSIZE];
>  
>       vec_root_size = vec_size = 0;
> -     head_size = SIZE(hlist_head);
> +
> +     if (STREQ(MEMBER_TYPE_NAME("tvec_root", "vec"), "list_head"))
> +             /* for RHEL7.6 or later */
> +             head_size = SIZE(list_head);
> +     else
> +             head_size = SIZE(hlist_head);
>  
>       if ((i = get_array_length("tvec_root.vec", NULL, head_size)))
>               vec_root_size = i;
> @@ -8414,15 +8419,15 @@ next_cpu:
>       init_tv_ranges(tv, vec_root_size, vec_size, cpu);
>  
>       count += do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec),
> -             vec_root_size, vec, NULL, NULL, NULL, 0);
> +             vec_root_size, vec, NULL, NULL, NULL, 0, head_size);
>       count += do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, NULL, NULL, NULL, 0);
> +             vec_size, vec, NULL, NULL, NULL, 0, head_size);
>       count += do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, NULL, NULL, NULL, 0);
> +             vec_size, vec, NULL, NULL, NULL, 0, head_size);
>       count += do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, NULL, NULL, NULL, 0);
> +             vec_size, vec, NULL, NULL, NULL, 0, head_size);
>       count += do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, NULL, NULL, NULL, 0);
> +             vec_size, vec, NULL, NULL, NULL, 0, head_size);
>  
>       if (count)
>               td = (struct timer_data *)
> @@ -8433,16 +8438,16 @@ next_cpu:
>  
>       get_symbol_data("jiffies", sizeof(ulong), &jiffies);
>  
> -     do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec),
> -             vec_root_size, vec, (void *)td, &highest, &highest_tte, 
> jiffies);
> -     do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, (void *)td, &highest, &highest_tte, jiffies);
> -     do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, (void *)td, &highest, &highest_tte, jiffies);
> -     do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, (void *)td, &highest, &highest_tte, jiffies);
> -     tdx = do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec),
> -             vec_size, vec, (void *)td, &highest, &highest_tte, jiffies);
> +     do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec), vec_root_size,
> +             vec, (void *)td, &highest, &highest_tte, jiffies, head_size);
> +     do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec), vec_size,
> +             vec, (void *)td, &highest, &highest_tte, jiffies, head_size);
> +     do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec), vec_size,
> +             vec, (void *)td, &highest, &highest_tte, jiffies, head_size);
> +     do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec), vec_size,
> +             vec, (void *)td, &highest, &highest_tte, jiffies, head_size);
> +     tdx = do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec), vec_size,
> +             vec, (void *)td, &highest, &highest_tte, jiffies, head_size);
>  
>       qsort(td, tdx, sizeof(struct timer_data), compare_timer_data);
>  
> @@ -8786,7 +8791,8 @@ do_timer_list_v3(ulong vec_kvaddr,
>             void *option,
>             ulong *highest,
>             ulong *highest_tte,
> -           ulong jiffies)
> +           ulong jiffies,
> +           long head_size)
>  {
>       int i, t;
>       int count, tdx;
> @@ -8804,19 +8810,24 @@ do_timer_list_v3(ulong vec_kvaddr,
>                       tdx++;
>       }
>  
> -     readmem(vec_kvaddr, KVADDR, vec, SIZE(hlist_head) * size,
> +     readmem(vec_kvaddr, KVADDR, vec, head_size * size,
>               "timer_list vec array", FAULT_ON_ERROR);
>  
>       ld = &list_data;
>       timer_list_buf = GETBUF(SIZE(timer_list));
>  
> -     for (i = count = 0; i < size; i++, vec_kvaddr += SIZE(hlist_head)) {
> +     for (i = count = 0; i < size; i++, vec_kvaddr += head_size) {
>  
> -             if (vec[i] == 0)
> -                     continue;
> +             if (head_size == SIZE(list_head)) {
> +                     if (vec[i*2] == vec_kvaddr)
> +                             continue;
> +             } else {
> +                     if (vec[i] == 0)
> +                             continue;
> +             }
>  
>               BZERO(ld, sizeof(struct list_data));
> -             ld->start = vec[i];
> +             ld->start = (head_size == SIZE(list_head)) ? vec[i*2] : vec[i];
>               ld->list_head_offset = OFFSET(timer_list_entry);
>               ld->end = vec_kvaddr;
>               ld->flags = RETURN_ON_LIST_ERROR;
> 
> 

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to