On Tue, Nov 18, 2025 at 3:13 PM HAGIO KAZUHITO(萩尾 一仁) <[email protected]>
wrote:

> Kernel commit 009eb5da29a9 ("hrtimer: Remove hrtimer_clock_base::
> Get_time") removed the get_time member from struct hrtimer_clock_base.
> As a result, the "timer -r" option fails with the following error:
>
>   crash> timer -r
>   timer: invalid structure member offset: hrtimer_clock_base_get_time
>           FILE: kernel.c  LINE: 7953  FUNCTION: dump_hrtimer_clock_base()
>
> As the get_time function is switched by __hrtimer_cb_get_time() function
> with clock_id macro value, crash cannot follow their changes
> automatically.  So change what "timer -r" displays there from the
> get_time function name to enum hrtimer_base_type name.
>
> Signed-off-by: Kazuhito Hagio <[email protected]>
> ---
> I refered to page_flags_init_from_pageflags_enum() function to use
> dump_enumerator_list(), pc->flags2 and etc.
>

Thank you for the fix, Kazu.
This looks good to me. For the patch: Ack

Lianbo


>
>  defs.h    |  1 +
>  kernel.c  | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++----
>  symbols.c |  2 ++
>  3 files changed, 73 insertions(+), 5 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index ab4aee8520a7..7f87e8e939e9 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2280,6 +2280,7 @@ struct offset_table {                    /* stash of
> commonly-used offsets */
>         long bpf_ringbuf_map_rb;
>         long bpf_ringbuf_consumer_pos;
>         long bpf_ringbuf_nr_pages;
> +       long hrtimer_clock_base_index;
>  };
>
>  struct size_table {         /* stash of commonly-used sizes */
> diff --git a/kernel.c b/kernel.c
> index 13f33742990e..ec287bb55c05 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -43,6 +43,7 @@ static void display_bh_1(void);
>  static void display_bh_2(void);
>  static void display_bh_3(void);
>  static void display_bh_4(void);
> +static int hrtimer_base_type_init(void);
>  static void dump_hrtimer_data(const ulong *cpus);
>  static void dump_hrtimer_clock_base(const void *, const int);
>  static void dump_hrtimer_base(const void *, const int);
> @@ -796,6 +797,12 @@ kernel_init()
>                         "hrtimer_clock_base", "first");
>                 MEMBER_OFFSET_INIT(hrtimer_clock_base_get_time,
>                         "hrtimer_clock_base", "get_time");
> +               if (INVALID_MEMBER(hrtimer_clock_base_get_time)) {
> +                       /* Linux 6.18: 009eb5da29a9 */
> +                       MEMBER_OFFSET_INIT(hrtimer_clock_base_index,
> "hrtimer_clock_base", "index");
> +                       if (!hrtimer_base_type_init())
> +                               error(WARNING, "cannot get enum
> hrtimer_base_type\n");
> +               }
>         }
>
>         STRUCT_SIZE_INIT(hrtimer_base, "hrtimer_base");
> @@ -7938,6 +7945,52 @@ static int expires_len = -1;
>  static int softexpires_len = -1;
>  static int tte_len = -1;
>
> +static char **hrtimer_base_type = NULL;
> +static int
> +hrtimer_base_type_init(void)
> +{
> +       long max_bases;
> +       int i, c ATTRIBUTE_UNUSED;
> +       char buf[BUFSIZE];
> +       char *arglist[MAXARGS];
> +
> +       if (!enumerator_value("HRTIMER_MAX_CLOCK_BASES", &max_bases))
> +               return FALSE;
> +
> +       hrtimer_base_type = (char **)calloc(max_bases, sizeof(char *));
> +       if (!hrtimer_base_type)
> +               return FALSE;
> +
> +       pc->flags2 |= ALLOW_FP; /* Required during initialization */
> +       open_tmpfile();
> +       if (dump_enumerator_list("hrtimer_base_type")) {
> +               rewind(pc->tmpfile);
> +               while (fgets(buf, BUFSIZE, pc->tmpfile)) {
> +                       if (!strstr(buf, " = "))
> +                               continue;
> +                       c = parse_line(buf, arglist);
> +                       i = atoi(arglist[2]);
> +                       if (0 <= i && i < max_bases)
> +                               hrtimer_base_type[i] = strdup(arglist[0]);
> +               }
> +               close_tmpfile();
> +               pc->flags2 &= ~ALLOW_FP;
> +       } else {
> +               close_tmpfile();
> +               pc->flags2 &= ~ALLOW_FP;
> +               free(hrtimer_base_type);
> +               hrtimer_base_type = NULL;
> +               return FALSE;
> +       }
> +
> +       if (CRASHDEBUG(1)) {
> +               for (i = 0; i < max_bases; i++)
> +                       fprintf(fp, "hrtimer_base_type[%d] = %s\n", i,
> hrtimer_base_type[i]);
> +       }
> +
> +       return TRUE;
> +}
> +
>  static void
>  dump_hrtimer_clock_base(const void *hrtimer_bases, const int num)
>  {
> @@ -7949,11 +8002,23 @@ dump_hrtimer_clock_base(const void *hrtimer_bases,
> const int num)
>
>         base = (void *)hrtimer_bases + OFFSET(hrtimer_cpu_base_clock_base)
> +
>                 SIZE(hrtimer_clock_base) * num;
> -       readmem((ulong)(base + OFFSET(hrtimer_clock_base_get_time)),
> KVADDR,
> -               &get_time, sizeof(get_time), "hrtimer_clock_base get_time",
> -               FAULT_ON_ERROR);
> -       fprintf(fp, "  CLOCK: %d  HRTIMER_CLOCK_BASE: %lx  [%s]\n", num,
> -               (ulong)base, value_to_symstr(get_time, buf, 0));
> +
> +       if (INVALID_MEMBER(hrtimer_clock_base_get_time)) {
> +               /* Linux 6.18: 009eb5da29a9 */
> +               if (hrtimer_base_type) {
> +                       uint index;
> +                       readmem((ulong)(base +
> OFFSET(hrtimer_clock_base_index)), KVADDR, &index,
> +                               sizeof(index), "hrtimer_clock_base index",
> FAULT_ON_ERROR);
> +                       fprintf(fp, "  CLOCK: %d  HRTIMER_CLOCK_BASE: %lx
> [%s]\n", num,
> +                               (ulong)base, hrtimer_base_type[index]);
> +               } else
> +                       fprintf(fp, "  CLOCK: %d  HRTIMER_CLOCK_BASE:
> %lx\n", num, (ulong)base);
> +       } else {
> +               readmem((ulong)(base +
> OFFSET(hrtimer_clock_base_get_time)), KVADDR, &get_time,
> +                       sizeof(get_time), "hrtimer_clock_base get_time",
> FAULT_ON_ERROR);
> +               fprintf(fp, "  CLOCK: %d  HRTIMER_CLOCK_BASE: %lx
> [%s]\n", num,
> +                       (ulong)base, value_to_symstr(get_time, buf, 0));
> +       }
>
>         /* get current time(uptime) */
>         get_uptime(NULL, &current_time);
> diff --git a/symbols.c b/symbols.c
> index 480fdb6d98b3..c446beb43a76 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -11760,6 +11760,8 @@ dump_offset_table(char *spec, ulong makestruct)
>                 OFFSET(hrtimer_clock_base_first));
>         fprintf(fp, "   hrtimer_clock_base_get_time: %ld\n",
>                 OFFSET(hrtimer_clock_base_get_time));
> +       fprintf(fp, "      hrtimer_clock_base_index: %ld\n",
> +               OFFSET(hrtimer_clock_base_index));
>         fprintf(fp, "            hrtimer_base_first: %ld\n",
>                 OFFSET(hrtimer_base_first));
>         fprintf(fp, "          hrtimer_base_pending: %ld\n",
> --
> 2.31.1
>
>
--
Crash-utility mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to