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, ¤t_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