[PATCH 3/6] rust: hrtimer: Add HrTimerClockBase

Lyude Paul
2025-04-02T21:41:36Z

This adds a simple wrapper for the hrtimer_clock_base struct, which can be
obtained from a HrTimerCallbackContext. We'll use this in the next commit to
add a function to acquire the current time for the base clock driving a
hrtimer.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
rust/kernel/time/hrtimer.rs | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)

diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs
index c92b10524f892..f633550882247 100644
--- a/rust/kernel/time/hrtimer.rs
+++ b/rust/kernel/time/hrtimer.rs
@@ -165,6 +165,29 @@ pub(crate) unsafe fn raw_cancel(this: *const Self) -> bool {
}
}

+/// The timer base for a specific clock.
+///
+/// # Invariants
+///
+/// The layout of this type is equivalent to that of `struct hrtimer_clock_base`.
+#[repr(transparent)]
+pub struct HrTimerClockBase(Opaque<bindings::hrtimer_clock_base>);
+
+impl HrTimerClockBase {
+ /// Retrieve a reference to a [`HrTimerClockBase`] from `ptr`.
+ ///
+ /// # Safety
+ ///
+ /// `ptr` must point to a live `struct hrtimer_clock_base`.
+ unsafe fn from_raw<'a>(ptr: *mut bindings::hrtimer_clock_base) -> &'a Self {
+ // SAFETY:
+ // - `ptr` is guaranteed to point to a live `struct hrtimer_clock_base` by our safety
+ // contract.
+ // - Our data layout is equivalent to said struct via our type invariants.
+ unsafe { &*ptr.cast() }
+ }
+}
+
/// Implemented by pointer types that point to structs that contain a [`HrTimer`].
///
/// `Self` must be [`Sync`] because it is passed to timer callbacks in another
@@ -506,6 +529,15 @@ pub(crate) fn raw_get_timer(&self) -> *mut bindings::hrtimer {
unsafe { HrTimer::raw_get(self.0.as_ptr()) }
}

+ /// Get the [`HrTimerClockBase`] for the [`HrTimer`] associated with this [`HrTimerCallbackContext`].
+ pub fn clock_base(&self) -> &HrTimerClockBase {
+ // SAFETY:
+ // - By our type invariants, `self.0` always points to a valid `HrTimer<T>`.
+ // - `base` is initialized and points to a valid `hrtimer_clock_base` for as long as
+ // `HrTimer<T>` is exposed to users.
+ unsafe { HrTimerClockBase::from_raw((*self.raw_get_timer()).base) }
+ }
+
/// Forward the timer expiry so it will expire in the future.
///
/// Note that this does not requeue the timer, it simply updates its expiry value. It returns
--
2.48.1