Using the HrTimer::raw_time_cb() function, we can now add an equivalent to
hrtimer_forward_now() to both HrTimer and HrTimerCallbackContext.
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
V2:
* Change from Ktime to Delta
* Make sure that forward_now() takes a mutable reference to the timer
struct
* Reword this to point out that we're adding forward_now() to both callback
context and mutable timer reference
* Rename interval to duration
V4:
* Fix rust documentation for HrTimerCallbackContext (forgot to update both
forward_now() declarations)
* Use Pin<&mut Self> for context-less forward.
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
rust/kernel/time/hrtimer.rs | 58 ++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index 79d86e1099a1e..0908359b0550a 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -201,7 +201,6 @@ unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Del
/// - The caller must ensure that the `hrtimer_clock_base` cannot possibly change in the context
/// this function is being called in. This means either exclusive access to `self_ptr` is
/// required, or we must be from within the timer callback context of `self_ptr`.
- #[expect(unused)]
unsafe fn raw_cb_time(self_ptr: *const Self) -> HrTimerInstant<T>
where
T: HasHrTimer<T>,
@@ -243,6 +242,44 @@ pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) ->
// exclusive access to it - fulfilling the requirements of the C API.
unsafe { Self::raw_forward(self.get_unchecked_mut(), now, interval) }
}
+
+ /// Conditionally forward the timer.
+ ///
+ /// This is a variant of [`forward()`](Self::forward) that uses an interval after the current
+ /// time of the base clock for the [`HrTimer`].
+ pub fn forward_now(self: Pin<&mut Self>, interval: Delta) -> u64
+ where
+ T: HasHrTimer<T>,
+ {
+ // SAFETY: `self` is a mutable reference, guaranteeing it is both a valid pointer to Self
+ // and that we also have exclusive access to `self`.
+ let now = unsafe { Self::raw_cb_time(&*self.as_ref()) };
+
+ self.forward(now, interval)
+ }
+
+ /// Return the time expiry for this [`HrTimer`].
+ ///
+ /// This value should only be used as a snapshot, as the actual expiry time could change after
+ /// this function is called.
+ pub fn expires(&self) -> HrTimerInstant<T>
+ where
+ T: HasHrTimer<T>,
+ {
+ // SAFETY: `self` is an immutable reference and thus always points to a valid `HrTimer`.
+ let c_timer_ptr = unsafe { HrTimer::raw_get(self) };
+
+ // SAFETY:
+ // - `node.expires` is a ktime_t, so it must be within the range of `0` to `KTIME_MAX`.
+ // - There's no actual locking here, a racy read is fine and expected
+ unsafe {
+ Instant::from_nanos(
+ // This `read_volatile` is intended to correspond to a READ_ONCE call.
+ // FIXME(read_once): Replace with `read_once` when available on the Rust side.
+ core::ptr::read_volatile(&raw const ((*c_timer_ptr).node.expires)),
+ )
+ }
+ }
}
/// Implemented by pointer types that point to structs that contain a [`HrTimer`].
@@ -702,6 +739,25 @@ pub fn forward(&mut self, now: HrTimerInstant<T>, interval: Delta) -> u64
// - By our type invariants, `self.0` always points to a valid `HrTimer<T>`
unsafe { HrTimer::<T>::raw_forward(self.0.as_ptr(), now, interval) }
}
+
+ /// Conditionally forward the timer.
+ ///
+ /// This is a variant of [`HrTimerCallbackContext::forward()`] that uses an interval after the
+ /// current time of the base clock for the [`HrTimer`].
+ pub fn forward_now(&mut self, duration: Delta) -> u64
+ where
+ T: HasHrTimer<T>,
+ {
+ self.forward(
+ // SAFETY:
+ // - We're guaranteed `self.0` points to a valid `HrTimer<T>` instance by type
+ // invariants.
+ // - We're guaranteed to be within the context of the timer callback by our type
+ // invariants.
+ unsafe { HrTimer::<T>::raw_cb_time(self.0.as_ptr()) },
+ duration,
+ )
+ }
}
/// Use to implement the [`HasHrTimer<T>`] trait.
--
2.49.0
"Lyude Paul" <lyude@redhat.com> writes: > Using the HrTimer::raw_time_cb() function, we can now add an equivalent to You called it `raw_cb_time`. > hrtimer_forward_now() to both HrTimer and HrTimerCallbackContext. > > Signed-off-by: Lyude Paul <lyude@redhat.com> > > --- > V2: > * Change from Ktime to Delta > * Make sure that forward_now() takes a mutable reference to the timer > struct > * Reword this to point out that we're adding forward_now() to both callback > context and mutable timer reference > * Rename interval to duration > > V4: > * Fix rust documentation for HrTimerCallbackContext (forgot to update both > forward_now() declarations) > * Use Pin<&mut Self> for context-less forward. > > Signed-off-by: Lyude Paul <lyude@redhat.com> > --- > rust/kernel/time/hrtimer.rs | 58 ++++++++++++++++++++++++++++++++++++- > 1 file changed, 57 insertions(+), 1 deletion(-) > > diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs > index 79d86e1099a1e..0908359b0550a 100644 > --- a/rust/kernel/time/hrtimer.rs > +++ b/rust/kernel/time/hrtimer.rs > @@ -201,7 +201,6 @@ unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Del > /// - The caller must ensure that the `hrtimer_clock_base` cannot possibly change in the context > /// this function is being called in. This means either exclusive access to `self_ptr` is > /// required, or we must be from within the timer callback context of `self_ptr`. > - #[expect(unused)] > unsafe fn raw_cb_time(self_ptr: *const Self) -> HrTimerInstant<T> > where > T: HasHrTimer<T>, > @@ -243,6 +242,44 @@ pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) -> > // exclusive access to it - fulfilling the requirements of the C API. > unsafe { Self::raw_forward(self.get_unchecked_mut(), now, interval) } > } > + > + /// Conditionally forward the timer. > + /// > + /// This is a variant of [`forward()`](Self::forward) that uses an interval after the current > + /// time of the base clock for the [`HrTimer`]. > + pub fn forward_now(self: Pin<&mut Self>, interval: Delta) -> u64 > + where > + T: HasHrTimer<T>, > + { > + // SAFETY: `self` is a mutable reference, guaranteeing it is both a valid pointer to Self > + // and that we also have exclusive access to `self`. > + let now = unsafe { Self::raw_cb_time(&*self.as_ref()) }; > + > + self.forward(now, interval) > + } > + > + /// Return the time expiry for this [`HrTimer`]. > + /// > + /// This value should only be used as a snapshot, as the actual expiry time could change after > + /// this function is called. > + pub fn expires(&self) -> HrTimerInstant<T> Commit message does not mention this method. Best regards, Andreas Hindborg
On Fri, 13 Jun 2025 19:22:28 -0400 Lyude Paul <lyude@redhat.com> wrote: > Using the HrTimer::raw_time_cb() function, we can now add an equivalent to > hrtimer_forward_now() to both HrTimer and HrTimerCallbackContext. > > Signed-off-by: Lyude Paul <lyude@redhat.com> > > --- > V2: > * Change from Ktime to Delta > * Make sure that forward_now() takes a mutable reference to the timer > struct > * Reword this to point out that we're adding forward_now() to both callback > context and mutable timer reference > * Rename interval to duration > > V4: > * Fix rust documentation for HrTimerCallbackContext (forgot to update both > forward_now() declarations) > * Use Pin<&mut Self> for context-less forward. > > Signed-off-by: Lyude Paul <lyude@redhat.com> > --- > rust/kernel/time/hrtimer.rs | 58 ++++++++++++++++++++++++++++++++++++- > 1 file changed, 57 insertions(+), 1 deletion(-) > > diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs > index 79d86e1099a1e..0908359b0550a 100644 > --- a/rust/kernel/time/hrtimer.rs > +++ b/rust/kernel/time/hrtimer.rs > @@ -201,7 +201,6 @@ unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Del > /// - The caller must ensure that the `hrtimer_clock_base` cannot possibly change in the context > /// this function is being called in. This means either exclusive access to `self_ptr` is > /// required, or we must be from within the timer callback context of `self_ptr`. > - #[expect(unused)] > unsafe fn raw_cb_time(self_ptr: *const Self) -> HrTimerInstant<T> > where > T: HasHrTimer<T>, > @@ -243,6 +242,44 @@ pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) -> > // exclusive access to it - fulfilling the requirements of the C API. > unsafe { Self::raw_forward(self.get_unchecked_mut(), now, interval) } > } > + > + /// Conditionally forward the timer. > + /// > + /// This is a variant of [`forward()`](Self::forward) that uses an interval after the current > + /// time of the base clock for the [`HrTimer`]. > + pub fn forward_now(self: Pin<&mut Self>, interval: Delta) -> u64 > + where > + T: HasHrTimer<T>, > + { > + // SAFETY: `self` is a mutable reference, guaranteeing it is both a valid pointer to Self > + // and that we also have exclusive access to `self`. > + let now = unsafe { Self::raw_cb_time(&*self.as_ref()) }; To the current time of the clock for the hrtimer, would it be possible to write it like the following instead? let now: Instant<<T::TimerMode as HrTimerMode>::Clock> = Instant::now(); Then we can drop #5 and #6 patches and remove some unsafe code. By the way, where can I find the latest rvkms code that uses this patchset?
© 2016 - 2025 Red Hat, Inc.