diff options
author | Lyude Paul <lyude@redhat.com> | 2025-08-21 15:32:43 -0400 |
---|---|---|
committer | Andreas Hindborg <a.hindborg@kernel.org> | 2025-09-04 16:54:39 +0200 |
commit | 3efb9ce91c5279d7ea73563d1fb136077f52dd2e (patch) | |
tree | aeb1203e03e9d62597cca35b59dfbd57ea7b012a | |
parent | 0e2aab67f2d5716e8db73b6d0719208b44086ed5 (diff) |
rust: hrtimer: Add HrTimer::raw_forward() and forward()
Within the hrtimer API there are quite a number of functions that can only
be safely called from one of two contexts:
* When we have exclusive access to the hrtimer and the timer is not active.
* When we're within the hrtimer's callback context as it is being executed.
This commit adds bindings for hrtimer_forward() for the first such context,
along with HrTimer::raw_forward() for later use in implementing the
hrtimer_forward() in the latter context.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250821193259.964504-4-lyude@redhat.com
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
-rw-r--r-- | rust/kernel/time/hrtimer.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index be1bad4aacaa..79fed14b2d98 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -168,6 +168,46 @@ impl<T> HrTimer<T> { // handled on the C side. unsafe { bindings::hrtimer_cancel(c_timer_ptr) != 0 } } + + /// Forward the timer expiry for a given timer pointer. + /// + /// # Safety + /// + /// - `self_ptr` must point to a valid `Self`. + /// - The caller must either have exclusive access to the data pointed at by `self_ptr`, or be + /// within the context of the timer callback. + #[inline] + unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Delta) -> u64 + where + T: HasHrTimer<T>, + { + // SAFETY: + // * The C API requirements for this function are fulfilled by our safety contract. + // * `self_ptr` is guaranteed to point to a valid `Self` via our safety contract + unsafe { + bindings::hrtimer_forward(Self::raw_get(self_ptr), now.as_nanos(), interval.as_nanos()) + } + } + + /// Conditionally forward the timer. + /// + /// If the timer expires after `now`, this function does nothing and returns 0. If the timer + /// expired at or before `now`, this function forwards the timer by `interval` until the timer + /// expires after `now` and then returns the number of times the timer was forwarded by + /// `interval`. + /// + /// Returns the number of overruns that occurred as a result of the timer expiry change. + pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) -> u64 + where + T: HasHrTimer<T>, + { + // SAFETY: `raw_forward` does not move `Self` + let this = unsafe { self.get_unchecked_mut() }; + + // SAFETY: By existence of `Pin<&mut Self>`, the pointer passed to `raw_forward` points to a + // valid `Self` that we have exclusive access to. + unsafe { Self::raw_forward(this, now, interval) } + } } /// Implemented by pointer types that point to structs that contain a [`HrTimer`]. |