* [PATCH v2 1/2] hrtimer: Add cleanup class for on-stack timers
2026-10-16 1:09 [PATCH v2 0/2] hrtimer: Add cleanup class for on-stack timers Hui Su
@ 2026-10-16 1:09 ` Hui Su
2026-10-16 1:09 ` [PATCH v2 2/2] sched/idle: Use hrtimer cleanup class in play_idle_precise() Hui Su
1 sibling, 0 replies; 3+ messages in thread
From: Hui Su @ 2026-10-16 1:09 UTC (permalink / raw)
To: anna-maria, frederic, tglx, mingo, peterz, juri.lelli, vincent.guittot
Cc: dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, rafael.j.wysocki, jacob.jun.pan, linux-kernel,
Hui Su
hrtimer_setup_on_stack() requires callers to destroy the timer before its
backing stack storage goes out of scope, but the setup interface does not
encode the required teardown pairing.
Add an hrtimer_on_stack cleanup class that pairs on-stack setup with
destroy_hrtimer_on_stack(). Document the existing setup API's lifetime
requirement.
The cleanup class provides debug-object teardown, not timer
cancellation. Callers must ensure that no hrtimer operation can still
access the timer before the scope ends; in particular, the timer must
no longer be queued and any running callback must have completed.
Signed-off-by: Hui Su <sh_def@163.com>
---
include/linux/hrtimer.h | 24 ++++++++++++++++++++++++
kernel/time/hrtimer.c | 8 ++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 29072d89e5cb..1877beb81d5c 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -12,6 +12,7 @@
#ifndef _LINUX_HRTIMER_H
#define _LINUX_HRTIMER_H
+#include <linux/cleanup.h>
#include <linux/hrtimer_rearm.h>
#include <linux/hrtimer_types.h>
#include <linux/init.h>
@@ -201,6 +202,29 @@ extern void destroy_hrtimer_on_stack(struct hrtimer *timer);
static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
#endif
+/*
+ * The cleanup class pairs on-stack setup with debug-object teardown. Callers
+ * using it must not call destroy_hrtimer_on_stack() manually.
+ *
+ * This class provides debug-object teardown, not timer cancellation. Callers
+ * must ensure that no hrtimer operation can still access the timer before
+ * leaving the scope. In particular, the timer must no longer be queued and
+ * any running callback must have completed.
+ *
+ * Callers using hrtimer_setup_on_stack() without this class retain
+ * responsibility for destroying the timer before its backing storage leaves
+ * scope.
+ */
+DEFINE_CLASS(hrtimer_on_stack, struct hrtimer *,
+ destroy_hrtimer_on_stack(_T),
+ ({
+ hrtimer_setup_on_stack(timer, function, clock_id, mode);
+ timer;
+ }),
+ struct hrtimer *timer,
+ enum hrtimer_restart (*function)(struct hrtimer *),
+ clockid_t clock_id, enum hrtimer_mode mode)
+
/* Basic timer operations: */
extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
u64 range_ns, const enum hrtimer_mode mode);
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index cbf1693c86b3..12e136d5691f 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1975,8 +1975,12 @@ EXPORT_SYMBOL_GPL(hrtimer_setup);
* @clock_id: The clock to be used
* @mode: The timer mode
*
- * Similar to hrtimer_setup(), except that this one must be used if struct hrtimer is in stack
- * memory.
+ * Similar to hrtimer_setup(), except that this one must be used if struct
+ * hrtimer is in stack memory.
+ *
+ * Callers that do not use the hrtimer_on_stack cleanup class must call
+ * destroy_hrtimer_on_stack() before the stack storage goes out of scope. The
+ * cleanup class pairs setup and destruction automatically.
*/
void hrtimer_setup_on_stack(struct hrtimer *timer,
enum hrtimer_restart (*function)(struct hrtimer *),
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2 2/2] sched/idle: Use hrtimer cleanup class in play_idle_precise()
2026-10-16 1:09 [PATCH v2 0/2] hrtimer: Add cleanup class for on-stack timers Hui Su
2026-10-16 1:09 ` [PATCH v2 1/2] " Hui Su
@ 2026-10-16 1:09 ` Hui Su
1 sibling, 0 replies; 3+ messages in thread
From: Hui Su @ 2026-10-16 1:09 UTC (permalink / raw)
To: anna-maria, frederic, tglx, mingo, peterz, juri.lelli, vincent.guittot
Cc: dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, rafael.j.wysocki, jacob.jun.pan, linux-kernel,
Hui Su
Pair on-stack setup with destruction using the hrtimer_on_stack cleanup
class in play_idle_precise().
Keep the cleanup object's scope around timer start and the idle wait. Start
the timer in pinned hard mode, so its callback runs as a hardirq on the
current CPU. The interrupted task observes it.done only after the callback
returns. Since the callback returns HRTIMER_NORESTART, the timer is not
requeued before the cleanup object tears down its on-stack debug object.
Fixes: c1de45ca831a ("sched/idle: Add support for tasks that inject idle")
Signed-off-by: Hui Su <sh_def@163.com>
---
kernel/sched/idle.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index eb73b65ce6c4..2880e01368b8 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -429,13 +429,17 @@ void play_idle_precise(u64 duration_ns, u64 latency_ns)
cpuidle_use_deepest_state(latency_ns);
it.done = 0;
- hrtimer_setup_on_stack(&it.timer, idle_inject_timer_fn, CLOCK_MONOTONIC,
- HRTIMER_MODE_REL_HARD);
- hrtimer_start(&it.timer, ns_to_ktime(duration_ns),
- HRTIMER_MODE_REL_PINNED_HARD);
+ {
+ CLASS(hrtimer_on_stack, timer)(&it.timer, idle_inject_timer_fn,
+ CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL_HARD);
- while (!READ_ONCE(it.done))
- do_idle();
+ hrtimer_start(timer, ns_to_ktime(duration_ns),
+ HRTIMER_MODE_REL_PINNED_HARD);
+
+ while (!READ_ONCE(it.done))
+ do_idle();
+ }
cpuidle_use_deepest_state(0);
current->flags &= ~PF_IDLE;
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread