applied: 
https://github.com/crash-utility/crash/commit/89e41397424a93b92cdc7d5458c33a317b2bd8f4

On Tue, Nov 18, 2025 at 10:49 PM lijiang <[email protected]> wrote:
>
> 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