[PATCH 00/12] hrtimer, timekeeping, tracing: various cleanups

STALE182d

13 messages, 1 author, 2026-03-11 · open the first message on its own page

[PATCH 00/12] hrtimer, timekeeping, tracing: various cleanups

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:18

Various, mostly trivial, cleanups and fixes to the timekeeping core and
hrtimer subsystems. These are preparations for another upcoming series,
so I'd like this to go together trough tip.

Tracing maintainers: Patch 2 touches the tracing core.

Based on tip/sched/hrtick.

---
Thomas Weißschuh (Schneider Electric) (12):
      scripts/gdb: timerlist: Adapt to move of tk_core
      tracing: Use explicit array size instead of sentinel elements in symbol printing
      timer_list: Print offset as signed integer
      timekeeping: auxclock: Consistently use raw timekeeper for tk_setup_internals()
      timekeeping: Mark offsets array as const
      hrtimer: Remove hrtimer_get_expires_ns()
      hrtimer: Don't zero-initialize ret in hrtimer_nanosleep()
      hrtimer: Drop spurious space in 'enum hrtimer_base_type'
      hrtimer: Drop unnecessary pointer indirection in hrtimer_expire_entry event
      hrtimer: Mark index and clockid of clock base as const
      hrtimer: Remove trailing comma after HRTIMER_MAX_CLOCK_BASES
      hrtimer: Add a helper to retrieve a hrtimer from its timerqueue node

 include/linux/hrtimer.h                    |  5 ----
 include/linux/hrtimer_defs.h               |  8 +++---
 include/linux/trace_events.h               | 13 ++++++----
 include/trace/events/timer.h               |  7 +++---
 include/trace/stages/stage3_trace_output.h | 40 +++++++++++++++---------------
 kernel/time/hrtimer.c                      | 14 ++++++-----
 kernel/time/timekeeping.c                  | 12 +++++----
 kernel/time/timer_list.c                   |  4 +--
 kernel/trace/trace_events_synth.c          |  4 +--
 kernel/trace/trace_output.c                | 20 +++++++++------
 kernel/trace/trace_syscalls.c              |  3 +--
 scripts/gdb/linux/timerlist.py             |  2 +-
 12 files changed, 68 insertions(+), 64 deletions(-)
---
base-commit: eef9f648fb0e92618041f019d4bdcf7ae17cb743
change-id: 20260311-hrtimer-cleanups-fd2deab892df

Best regards,
-- 
Thomas Weißschuh [off-list ref]

[PATCH 01/12] scripts/gdb: timerlist: Adapt to move of tk_core

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:20

tk_core is a macro today which can not be resolved by gdb.

Use the correct symbol expression to reference tk_core.

Fixes: 22c62b9a84b8 ("timekeeping: Introduce auxiliary timekeepers")
Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 scripts/gdb/linux/timerlist.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py
index ccc24d30de80..9fb3436a217c 100644
--- a/scripts/gdb/linux/timerlist.py
+++ b/scripts/gdb/linux/timerlist.py
@@ -20,7 +20,7 @@ def ktime_get():
     We can't read the hardware timer itself to add any nanoseconds
     that need to be added since we last stored the time in the
     timekeeper. But this is probably good enough for debug purposes."""
-    tk_core = gdb.parse_and_eval("&tk_core")
+    tk_core = gdb.parse_and_eval("&timekeeper_data[TIMEKEEPER_CORE]")
 
     return tk_core['timekeeper']['tkr_mono']['base']
 
-- 
2.53.0

[PATCH 02/12] tracing: Use explicit array size instead of sentinel elements in symbol printing

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:20

The sentinel value added by the wrapper macros __print_symbolic() et al
prevents the callers from adding their own trailing comma. This makes
constructing symbol list dynamically based on kconfig values tedious.

Drop the sentinel elements, so callers can either specify the trailing
comma or not, just like in regular array initializers.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 include/linux/trace_events.h               | 13 ++++++----
 include/trace/stages/stage3_trace_output.h | 40 +++++++++++++++---------------
 kernel/trace/trace_events_synth.c          |  4 +--
 kernel/trace/trace_output.c                | 20 +++++++++------
 kernel/trace/trace_syscalls.c              |  3 +--
 5 files changed, 43 insertions(+), 37 deletions(-)
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 37eb2f0f3dd8..40a43a4c7caf 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -22,20 +22,23 @@ union bpf_attr;
 
 const char *trace_print_flags_seq(struct trace_seq *p, const char *delim,
 				  unsigned long flags,
-				  const struct trace_print_flags *flag_array);
+				  const struct trace_print_flags *flag_array,
+				  size_t flag_array_size);
 
 const char *trace_print_symbols_seq(struct trace_seq *p, unsigned long val,
-				    const struct trace_print_flags *symbol_array);
+				    const struct trace_print_flags *symbol_array,
+				    size_t symbol_array_size);
 
 #if BITS_PER_LONG == 32
 const char *trace_print_flags_seq_u64(struct trace_seq *p, const char *delim,
 		      unsigned long long flags,
-		      const struct trace_print_flags_u64 *flag_array);
+		      const struct trace_print_flags_u64 *flag_array,
+		      size_t flag_array_size);
 
 const char *trace_print_symbols_seq_u64(struct trace_seq *p,
 					unsigned long long val,
-					const struct trace_print_flags_u64
-								 *symbol_array);
+					const struct trace_print_flags_u64 *symbol_array,
+					size_t symbol_array_size);
 #endif
 
 struct trace_iterator;
diff --git a/include/trace/stages/stage3_trace_output.h b/include/trace/stages/stage3_trace_output.h
index fce85ea2df1c..b7d8ef4b9fe1 100644
--- a/include/trace/stages/stage3_trace_output.h
+++ b/include/trace/stages/stage3_trace_output.h
@@ -64,36 +64,36 @@
 #define __get_rel_sockaddr(field)	((struct sockaddr *)__get_rel_dynamic_array(field))
 
 #undef __print_flags
-#define __print_flags(flag, delim, flag_array...)			\
-	({								\
-		static const struct trace_print_flags __flags[] =	\
-			{ flag_array, { -1, NULL }};			\
-		trace_print_flags_seq(p, delim, flag, __flags);	\
+#define __print_flags(flag, delim, flag_array...)					\
+	({										\
+		static const struct trace_print_flags __flags[] =			\
+			{ flag_array };							\
+		trace_print_flags_seq(p, delim, flag, __flags, ARRAY_SIZE(__flags));	\
 	})
 
 #undef __print_symbolic
-#define __print_symbolic(value, symbol_array...)			\
-	({								\
-		static const struct trace_print_flags symbols[] =	\
-			{ symbol_array, { -1, NULL }};			\
-		trace_print_symbols_seq(p, value, symbols);		\
+#define __print_symbolic(value, symbol_array...)					\
+	({										\
+		static const struct trace_print_flags symbols[] =			\
+			{ symbol_array };						\
+		trace_print_symbols_seq(p, value, symbols, ARRAY_SIZE(symbols));	\
 	})
 
 #undef __print_flags_u64
 #undef __print_symbolic_u64
 #if BITS_PER_LONG == 32
-#define __print_flags_u64(flag, delim, flag_array...)			\
-	({								\
-		static const struct trace_print_flags_u64 __flags[] =	\
-			{ flag_array, { -1, NULL } };			\
-		trace_print_flags_seq_u64(p, delim, flag, __flags);	\
+#define __print_flags_u64(flag, delim, flag_array...)						\
+	({											\
+		static const struct trace_print_flags_u64 __flags[] =				\
+			{ flag_array };								\
+		trace_print_flags_seq_u64(p, delim, flag, __flags, ARRAY_SIZE(__flags));	\
 	})
 
-#define __print_symbolic_u64(value, symbol_array...)			\
-	({								\
-		static const struct trace_print_flags_u64 symbols[] =	\
-			{ symbol_array, { -1, NULL } };			\
-		trace_print_symbols_seq_u64(p, value, symbols);	\
+#define __print_symbolic_u64(value, symbol_array...)					\
+	({										\
+		static const struct trace_print_flags_u64 symbols[] =			\
+			{ symbol_array };						\
+		trace_print_symbols_seq_u64(p, value, symbols, ARRAY_SIZE(symbols));	\
 	})
 #else
 #define __print_flags_u64(flag, delim, flag_array...)			\
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index 8bb95b2a6fcf..39ac4eba0702 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -395,7 +395,7 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter,
 			n_u64++;
 		} else {
 			struct trace_print_flags __flags[] = {
-			    __def_gfpflag_names, {-1, NULL} };
+			    __def_gfpflag_names };
 			char *space = (i == se->n_fields - 1 ? "" : " ");
 
 			print_synth_event_num_val(s, print_fmt,
@@ -408,7 +408,7 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter,
 				trace_seq_puts(s, " (");
 				trace_print_flags_seq(s, "|",
 						      entry->fields[n_u64].as_u64,
-						      __flags);
+						      __flags, ARRAY_SIZE(__flags));
 				trace_seq_putc(s, ')');
 			}
 			n_u64++;
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 1996d7aba038..96e2d22b4364 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -69,14 +69,15 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
 const char *
 trace_print_flags_seq(struct trace_seq *p, const char *delim,
 		      unsigned long flags,
-		      const struct trace_print_flags *flag_array)
+		      const struct trace_print_flags *flag_array,
+		      size_t flag_array_size)
 {
 	unsigned long mask;
 	const char *str;
 	const char *ret = trace_seq_buffer_ptr(p);
 	int i, first = 1;
 
-	for (i = 0;  flag_array[i].name && flags; i++) {
+	for (i = 0; i < flag_array_size && flags; i++) {
 
 		mask = flag_array[i].mask;
 		if ((flags & mask) != mask)
@@ -106,12 +107,13 @@ EXPORT_SYMBOL(trace_print_flags_seq);
 
 const char *
 trace_print_symbols_seq(struct trace_seq *p, unsigned long val,
-			const struct trace_print_flags *symbol_array)
+			const struct trace_print_flags *symbol_array,
+			size_t symbol_array_size)
 {
 	int i;
 	const char *ret = trace_seq_buffer_ptr(p);
 
-	for (i = 0;  symbol_array[i].name; i++) {
+	for (i = 0; i < symbol_array_size; i++) {
 
 		if (val != symbol_array[i].mask)
 			continue;
@@ -133,14 +135,15 @@ EXPORT_SYMBOL(trace_print_symbols_seq);
 const char *
 trace_print_flags_seq_u64(struct trace_seq *p, const char *delim,
 		      unsigned long long flags,
-		      const struct trace_print_flags_u64 *flag_array)
+		      const struct trace_print_flags_u64 *flag_array,
+		      size_t flag_array_size)
 {
 	unsigned long long mask;
 	const char *str;
 	const char *ret = trace_seq_buffer_ptr(p);
 	int i, first = 1;
 
-	for (i = 0;  flag_array[i].name && flags; i++) {
+	for (i = 0; i < flag_array_size && flags; i++) {
 
 		mask = flag_array[i].mask;
 		if ((flags & mask) != mask)
@@ -170,12 +173,13 @@ EXPORT_SYMBOL(trace_print_flags_seq_u64);
 
 const char *
 trace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
-			 const struct trace_print_flags_u64 *symbol_array)
+			    const struct trace_print_flags_u64 *symbol_array,
+			    size_t symbol_array_size)
 {
 	int i;
 	const char *ret = trace_seq_buffer_ptr(p);
 
-	for (i = 0;  symbol_array[i].name; i++) {
+	for (i = 0; i < symbol_array_size; i++) {
 
 		if (val != symbol_array[i].mask)
 			continue;
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 37317b81fcda..8ad72e17d8eb 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -174,7 +174,6 @@ sys_enter_openat_print(struct syscall_trace_enter *trace, struct syscall_metadat
 			{ O_NOFOLLOW, "O_NOFOLLOW" },
 			{ O_NOATIME, "O_NOATIME" },
 			{ O_CLOEXEC, "O_CLOEXEC" },
-			{ -1, NULL }
 		};
 
 	trace_seq_printf(s, "%s(", entry->name);
@@ -205,7 +204,7 @@ sys_enter_openat_print(struct syscall_trace_enter *trace, struct syscall_metadat
 				trace_seq_puts(s, "O_RDONLY|");
 			}
 
-			trace_print_flags_seq(s, "|", bits, __flags);
+			trace_print_flags_seq(s, "|", bits, __flags, ARRAY_SIZE(__flags));
 			/*
 			 * trace_print_flags_seq() adds a '\0' to the
 			 * buffer, but this needs to append more to the seq.
-- 
2.53.0

[PATCH 03/12] timer_list: Print offset as signed integer

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:21

The offset of a hrtimer base may be negative.

Print those values correctly.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 kernel/time/timer_list.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index e2e14fd1b466..427d7ddea3af 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -101,8 +101,8 @@ print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
 
 	SEQ_printf(m, "  .resolution: %u nsecs\n", hrtimer_resolution);
 #ifdef CONFIG_HIGH_RES_TIMERS
-	SEQ_printf(m, "  .offset:     %Lu nsecs\n",
-		   (unsigned long long) ktime_to_ns(base->offset));
+	SEQ_printf(m, "  .offset:     %Ld nsecs\n",
+		   (long long) base->offset);
 #endif
 	SEQ_printf(m,   "active timers:\n");
 	print_active_timers(m, base, now + ktime_to_ns(base->offset));
-- 
2.53.0

[PATCH 04/12] timekeeping: auxclock: Consistently use raw timekeeper for tk_setup_internals()

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:21

In aux_clock_enable() the clocksource from tkr_raw is used to call
tk_setup_internals(). Do the same in tk_aux_update_clocksource().
While the clocksources will be the same in any case, this is less
confusing.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 kernel/time/timekeeping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 5153218df29f..46b77c3deb95 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -2985,7 +2985,7 @@ static void tk_aux_update_clocksource(void)
 			continue;
 
 		timekeeping_forward_now(tks);
-		tk_setup_internals(tks, tk_core.timekeeper.tkr_mono.clock);
+		tk_setup_internals(tks, tk_core.timekeeper.tkr_raw.clock);
 		timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL);
 	}
 }
-- 
2.53.0

[PATCH 05/12] timekeeping: Mark offsets array as const

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:22

Neither the array nor the offsets it is pointing to are meant to be
changed through the array.

Mark both the array and the values it points to as const.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 kernel/time/timekeeping.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 46b77c3deb95..27f17428f7c5 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -989,7 +989,7 @@ u32 ktime_get_resolution_ns(void)
 }
 EXPORT_SYMBOL_GPL(ktime_get_resolution_ns);
 
-static ktime_t *offsets[TK_OFFS_MAX] = {
+static const ktime_t *const offsets[TK_OFFS_MAX] = {
 	[TK_OFFS_REAL]	= &tk_core.timekeeper.offs_real,
 	[TK_OFFS_BOOT]	= &tk_core.timekeeper.offs_boot,
 	[TK_OFFS_TAI]	= &tk_core.timekeeper.offs_tai,
@@ -998,8 +998,9 @@ static ktime_t *offsets[TK_OFFS_MAX] = {
 ktime_t ktime_get_with_offset(enum tk_offsets offs)
 {
 	struct timekeeper *tk = &tk_core.timekeeper;
+	const ktime_t *offset = offsets[offs];
 	unsigned int seq;
-	ktime_t base, *offset = offsets[offs];
+	ktime_t base;
 	u64 nsecs;
 
 	WARN_ON(timekeeping_suspended);
@@ -1019,8 +1020,9 @@ EXPORT_SYMBOL_GPL(ktime_get_with_offset);
 ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs)
 {
 	struct timekeeper *tk = &tk_core.timekeeper;
-	ktime_t base, *offset = offsets[offs];
+	const ktime_t *offset = offsets[offs];
 	unsigned int seq;
+	ktime_t base;
 	u64 nsecs;
 
 	WARN_ON(timekeeping_suspended);
@@ -1043,7 +1045,7 @@ EXPORT_SYMBOL_GPL(ktime_get_coarse_with_offset);
  */
 ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs)
 {
-	ktime_t *offset = offsets[offs];
+	const ktime_t *offset = offsets[offs];
 	unsigned int seq;
 	ktime_t tconv;
 
-- 
2.53.0

[PATCH 06/12] hrtimer: Remove hrtimer_get_expires_ns()

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:22

There are no users left.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 include/linux/hrtimer.h | 5 -----
 1 file changed, 5 deletions(-)
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index c087b7142330..9ced498fefaa 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -116,11 +116,6 @@ static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer)
 	return timer->_softexpires;
 }
 
-static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer)
-{
-	return ktime_to_ns(timer->node.expires);
-}
-
 ktime_t hrtimer_cb_get_time(const struct hrtimer *timer);
 
 static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)
-- 
2.53.0

[PATCH 07/12] hrtimer: Don't zero-initialize ret in hrtimer_nanosleep()

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:23

The value will be assigned to before any usage.
No other function in hrtimer.c does such a zero-initialization.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 kernel/time/hrtimer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index b94bd56b739f..226cac8c82cc 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -2328,7 +2328,7 @@ long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode, const clockid
 {
 	struct restart_block *restart;
 	struct hrtimer_sleeper t;
-	int ret = 0;
+	int ret;
 
 	hrtimer_setup_sleeper_on_stack(&t, clockid, mode);
 	hrtimer_set_expires_range_ns(&t.timer, rqtp, current->timer_slack_ns);
-- 
2.53.0

[PATCH 08/12] hrtimer: Drop spurious space in 'enum hrtimer_base_type'

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:24

This spurious space makes grepping for the enum definition annoying.

Remove it.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 include/linux/hrtimer_defs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/hrtimer_defs.h b/include/linux/hrtimer_defs.h
index 0f851b2432c3..e6d4dc1b61e0 100644
--- a/include/linux/hrtimer_defs.h
+++ b/include/linux/hrtimer_defs.h
@@ -35,7 +35,7 @@ struct hrtimer_clock_base {
 	ktime_t				offset;
 } __hrtimer_clock_base_align;
 
-enum  hrtimer_base_type {
+enum hrtimer_base_type {
 	HRTIMER_BASE_MONOTONIC,
 	HRTIMER_BASE_REALTIME,
 	HRTIMER_BASE_BOOTTIME,
-- 
2.53.0

[PATCH 09/12] hrtimer: Drop unnecessary pointer indirection in hrtimer_expire_entry event

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:25

This pointer indirection is a remnant from when ktime_t was a struct,
today it is pointless.

Drop the pointer indirection.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 include/trace/events/timer.h | 7 +++----
 kernel/time/hrtimer.c        | 4 ++--
 2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
index a54613f59e55..07cbb9836b91 100644
--- a/include/trace/events/timer.h
+++ b/include/trace/events/timer.h
@@ -254,14 +254,13 @@ TRACE_EVENT(hrtimer_start,
 /**
  * hrtimer_expire_entry - called immediately before the hrtimer callback
  * @hrtimer:	pointer to struct hrtimer
- * @now:	pointer to variable which contains current time of the
- *		timers base.
+ * @now:	variable which contains current time of the timers base.
  *
  * Allows to determine the timer latency.
  */
 TRACE_EVENT(hrtimer_expire_entry,
 
-	TP_PROTO(struct hrtimer *hrtimer, ktime_t *now),
+	TP_PROTO(struct hrtimer *hrtimer, ktime_t now),
 
 	TP_ARGS(hrtimer, now),
 
@@ -273,7 +272,7 @@ TRACE_EVENT(hrtimer_expire_entry,
 
 	TP_fast_assign(
 		__entry->hrtimer	= hrtimer;
-		__entry->now		= *now;
+		__entry->now		= now;
 		__entry->function	= ACCESS_PRIVATE(hrtimer, function);
 	),
 
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 226cac8c82cc..d350bceb3c95 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1884,7 +1884,7 @@ EXPORT_SYMBOL_GPL(hrtimer_active);
  * __run_hrtimer() invocations.
  */
 static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, struct hrtimer_clock_base *base,
-			  struct hrtimer *timer, ktime_t *now, unsigned long flags)
+			  struct hrtimer *timer, ktime_t now, unsigned long flags)
 	__must_hold(&cpu_base->lock)
 {
 	enum hrtimer_restart (*fn)(struct hrtimer *);
@@ -1989,7 +1989,7 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
 			if (basenow < hrtimer_get_softexpires(timer))
 				break;
 
-			__run_hrtimer(cpu_base, base, timer, &basenow, flags);
+			__run_hrtimer(cpu_base, base, timer, basenow, flags);
 			if (active_mask == HRTIMER_ACTIVE_SOFT)
 				hrtimer_sync_wait_running(cpu_base, flags);
 		}
-- 
2.53.0

[PATCH 10/12] hrtimer: Mark index and clockid of clock base as const

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:25

These fields are initialized once and are never supposed to change.

Mark them as const to make this explicit.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 include/linux/hrtimer_defs.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/hrtimer_defs.h b/include/linux/hrtimer_defs.h
index e6d4dc1b61e0..a03240c0b14f 100644
--- a/include/linux/hrtimer_defs.h
+++ b/include/linux/hrtimer_defs.h
@@ -26,8 +26,8 @@
  */
 struct hrtimer_clock_base {
 	struct hrtimer_cpu_base		*cpu_base;
-	unsigned int			index;
-	clockid_t			clockid;
+	const unsigned int		index;
+	const clockid_t			clockid;
 	seqcount_raw_spinlock_t		seq;
 	ktime_t				expires_next;
 	struct hrtimer			*running;
-- 
2.53.0

[PATCH 11/12] hrtimer: Remove trailing comma after HRTIMER_MAX_CLOCK_BASES

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:26

HRTIMER_MAX_CLOCK_BASES is required to stay the last value of the enum.

Drop the trailing comma so no new members are added after it by mistake.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 include/linux/hrtimer_defs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/hrtimer_defs.h b/include/linux/hrtimer_defs.h
index a03240c0b14f..52ed9e46ff13 100644
--- a/include/linux/hrtimer_defs.h
+++ b/include/linux/hrtimer_defs.h
@@ -44,7 +44,7 @@ enum hrtimer_base_type {
 	HRTIMER_BASE_REALTIME_SOFT,
 	HRTIMER_BASE_BOOTTIME_SOFT,
 	HRTIMER_BASE_TAI_SOFT,
-	HRTIMER_MAX_CLOCK_BASES,
+	HRTIMER_MAX_CLOCK_BASES
 };
 
 /**
-- 
2.53.0

[PATCH 12/12] hrtimer: Add a helper to retrieve a hrtimer from its timerqueue node

From: Thomas Weißschuh (Schneider Electric) <hidden>
Date: 2026-03-11 10:16:26

The container_of() call is open-coded multiple times.

Add a helper macro.

Use container_of_const() to preserve constness.

Signed-off-by: Thomas Weißschuh (Schneider Electric) <redacted>
---
 kernel/time/hrtimer.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index d350bceb3c95..94955f967207 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -534,6 +534,8 @@ static inline void debug_activate(struct hrtimer *timer, enum hrtimer_mode mode,
 		for (bool done = false; !done; active &= ~(1U << idx))			\
 			for (base = &cpu_base->clock_base[idx]; !done; done = true)
 
+#define hrtimer_from_timerqueue_node(_n) container_of_const(_n, struct hrtimer, node)
+
 #if defined(CONFIG_NO_HZ_COMMON)
 /*
  * Same as hrtimer_bases_next_event() below, but skips the excluded timer and
@@ -578,7 +580,7 @@ static __always_inline struct hrtimer *clock_base_next_timer(struct hrtimer_cloc
 {
 	struct timerqueue_linked_node *next = timerqueue_linked_first(&base->active);
 
-	return container_of(next, struct hrtimer, node);
+	return hrtimer_from_timerqueue_node(next);
 }
 
 /* Find the base with the earliest expiry */
@@ -1960,7 +1962,7 @@ static __always_inline struct hrtimer *clock_base_next_timer_safe(struct hrtimer
 {
 	struct timerqueue_linked_node *next = timerqueue_linked_first(&base->active);
 
-	return next ? container_of(next, struct hrtimer, node) : NULL;
+	return next ? hrtimer_from_timerqueue_node(next) : NULL;
 }
 
 static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
@@ -2438,7 +2440,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
 	struct hrtimer *timer;
 
 	while ((node = timerqueue_linked_first(&old_base->active))) {
-		timer = container_of(node, struct hrtimer, node);
+		timer = hrtimer_from_timerqueue_node(node);
 		BUG_ON(hrtimer_callback_running(timer));
 		debug_hrtimer_deactivate(timer);
 
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help