* [PATCH v3] rust: hrtimer: add active() method to query timer state
@ 2026-11-05 10:17 Andreas Hindborg
2026-11-05 11:11 ` FUJITA Tomonori
0 siblings, 1 reply; 2+ messages in thread
From: Andreas Hindborg @ 2026-11-05 10:17 UTC (permalink / raw)
To: Boqun Feng, FUJITA Tomonori, Frederic Weisbecker, Lyude Paul,
Thomas Gleixner, Anna-Maria Behnsen, John Stultz, Stephen Boyd,
Miguel Ojeda, Gary Guo, Björn Roy Baron, Benno Lossin,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Daniel Almeida,
Tamir Duberstein, Alexandre Courbot, Onur Özkan
Cc: rust-for-linux, linux-kernel, Andreas Hindborg
Add an `active()` method to HrTimer that returns true if the timer is in
the started or running states. This wraps the kernel's hrtimer_active()
function.
Unlike a direct read of `node.expires`, this does not race with a
concurrent start operation. hrtimer_active() reads the timer state inside a
seqcount retry loop and re-reads `timer->base` with READ_ONCE(), and the
core documents that it must not return a false negative. No exclusive
access to the timer is therefore required, and the SAFETY comment reflects
that.
The returned value is still only a snapshot: a concurrent start or an
expiry can change the state right after the call. Callers that need a
stable answer have to serialize against those operations themselves,
exactly as C callers of hrtimer_active() do. This is documented on the
method.
Also add documentation clarifying the definition of an active timer.
Introduce the term `active` as a set of timer states composed of `started`
and `running`.
Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
Changes in v3:
- Rebase on v7.4-rc1.
- Improve documentation.
- Move the note about not requiring exclusive access above the example.
- Name the user of the API below the cut.
- Link to v2: https://msgid.link/20260605-hrtimer-active-v2-1-77d755c81fd7@kernel.org
Changes in v2:
- Mark `active()` `#[inline]` (Gary).
- Use the `[`true`]` intra-doc link in the rustdoc (Miguel).
- Document that `active()` does not require exclusive access to the timer,
and reflect this in the SAFETY comment (Gary).
- Add a doctest example that initializes a timer and asserts it is not
active (Miguel).
- Link to v1: https://msgid.link/20260215-hrtimer-active-v1-1-a754d10492c2@kernel.org
---
The bandwidth throttling timer in the Rust null block driver will call this
function. It is used to arm the timer on request submission if it is not
already armed.
---
rust/kernel/time/hrtimer.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index a53f7f1341be..45bbe3530f8c 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -71,6 +71,8 @@
//! issue the `start` operation while the timer is in the **started** state. In
//! this case the `start` operation is equivalent to the `restart` operation.
//!
+//! A timer is **active** if it is either in the **started** or **running** states.
+//!
//! # Examples
//!
//! ## Using an intrusive timer living in a [`Box`]
@@ -593,6 +595,68 @@ pub fn expires(&self) -> HrTimerInstant<T>
)
}
}
+
+ /// Query the state of the timer.
+ ///
+ /// Returns [`true`] if the timer is in the started or running states.
+ ///
+ /// This method synchronizes internally and does not require exclusive access to the timer.
+ ///
+ /// The returned value is a snapshot. A concurrent start or expiry can change the state of the
+ /// timer right after this method returns, so callers that need the state to be stable must
+ /// serialize against those operations by other means.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use kernel::{
+ /// # impl_has_hr_timer,
+ /// # prelude::*,
+ /// # time::{
+ /// # hrtimer::{
+ /// # HasHrTimer, HrTimer, HrTimerCallback, HrTimerCallbackContext,
+ /// # HrTimerRestart, RelativeMode,
+ /// # },
+ /// # Monotonic,
+ /// # },
+ /// # };
+ /// # use pin_init::stack_pin_init;
+ /// #[pin_data]
+ /// struct ExampleTimer {
+ /// #[pin]
+ /// timer: HrTimer<Self>,
+ /// }
+ ///
+ /// impl ExampleTimer {
+ /// fn new() -> impl PinInit<Self> {
+ /// pin_init!(Self { timer <- HrTimer::new() })
+ /// }
+ /// }
+ ///
+ /// impl HrTimerCallback for ExampleTimer {
+ /// type Pointer<'a> = Pin<&'a Self>;
+ /// fn run(_this: Pin<&Self>, _ctx: HrTimerCallbackContext<'_, Self>) -> HrTimerRestart {
+ /// HrTimerRestart::NoRestart
+ /// }
+ /// }
+ ///
+ /// impl_has_hr_timer! {
+ /// impl HasHrTimer<Self> for ExampleTimer {
+ /// mode: RelativeMode<Monotonic>, field: self.timer
+ /// }
+ /// }
+ ///
+ /// stack_pin_init!(let has_timer = ExampleTimer::new());
+ /// assert!(!has_timer.timer.active());
+ /// # Ok::<(), kernel::error::Error>(())
+ /// ```
+ #[inline]
+ pub fn active(&self) -> bool {
+ // SAFETY: By type invariant, `self.timer` is valid. `hrtimer_active`
+ // synchronizes internally and is safe to call without exclusive
+ // access to the timer.
+ unsafe { bindings::hrtimer_active(self.timer.get()) }
+ }
}
/// Implemented by pointer types that point to structs that contain a [`HrTimer`].
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20260215-hrtimer-active-f183411fe56b
Best regards,
--
Andreas Hindborg <a.hindborg@kernel.org>
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v3] rust: hrtimer: add active() method to query timer state
2026-11-05 10:17 [PATCH v3] rust: hrtimer: add active() method to query timer state Andreas Hindborg
@ 2026-11-05 11:11 ` FUJITA Tomonori
0 siblings, 0 replies; 2+ messages in thread
From: FUJITA Tomonori @ 2026-11-05 11:11 UTC (permalink / raw)
To: a.hindborg
Cc: boqun, fujita.tomonori, frederic, lyude, tglx, anna-maria,
jstultz, sboyd, ojeda, gary, bjorn3_gh, lossin, aliceryhl,
tmgross, dakr, daniel.almeida, tamird, acourbot, work,
rust-for-linux, linux-kernel
On Thu, 05 Nov 2026 11:17:24 +0100
Andreas Hindborg <a.hindborg@kernel.org> wrote:
> Add an `active()` method to HrTimer that returns true if the timer is in
> the started or running states. This wraps the kernel's hrtimer_active()
> function.
>
> Unlike a direct read of `node.expires`, this does not race with a
> concurrent start operation. hrtimer_active() reads the timer state inside a
> seqcount retry loop and re-reads `timer->base` with READ_ONCE(), and the
> core documents that it must not return a false negative. No exclusive
> access to the timer is therefore required, and the SAFETY comment reflects
> that.
>
> The returned value is still only a snapshot: a concurrent start or an
> expiry can change the state right after the call. Callers that need a
> stable answer have to serialize against those operations themselves,
> exactly as C callers of hrtimer_active() do. This is documented on the
> method.
>
> Also add documentation clarifying the definition of an active timer.
>
> Introduce the term `active` as a set of timer states composed of `started`
> and `running`.
>
> Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
[...]
> + /// Query the state of the timer.
> + ///
> + /// Returns [`true`] if the timer is in the started or running states.
> + ///
> + /// This method synchronizes internally and does not require exclusive access to the timer.
> + ///
> + /// The returned value is a snapshot. A concurrent start or expiry can change the state of the
> + /// timer right after this method returns, so callers that need the state to be stable must
> + /// serialize against those operations by other means.
Does "expiry" here mean that the callback returns HrTimerRestart::NoRestart
on another CPU? An expiry alone moves the timer from started to running, so
active() still returns true. If so, I think it is clearer to write this case
directly, and to add the case where the timer is canceled on another CPU.
The same sentence is in the commit message, so please update it too.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-05 11:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-05 10:17 [PATCH v3] rust: hrtimer: add active() method to query timer state Andreas Hindborg
2026-11-05 11:11 ` FUJITA Tomonori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®