kernel/time/hrtimer.rs
1// SPDX-License-Identifier: GPL-2.0
2
3//! Intrusive high resolution timers.
4//!
5//! Allows running timer callbacks without doing allocations at the time of
6//! starting the timer. For now, only one timer per type is allowed.
7//!
8//! # Vocabulary
9//!
10//! States:
11//!
12//! - Stopped: initialized but not started, or cancelled, or not restarted.
13//! - Started: initialized and started or restarted.
14//! - Running: executing the callback.
15//!
16//! Operations:
17//!
18//! * Start
19//! * Cancel
20//! * Restart
21//!
22//! Events:
23//!
24//! * Expire
25//!
26//! ## State Diagram
27//!
28//! ```text
29//! Return NoRestart
30//! +---------------------------------------------------------------------+
31//! | |
32//! | |
33//! | |
34//! | Return Restart |
35//! | +------------------------+ |
36//! | | | |
37//! | | | |
38//! v v | |
39//! +-----------------+ Start +------------------+ +--------+-----+--+
40//! | +---------------->| | | |
41//! Init | | | | Expire | |
42//! --------->| Stopped | | Started +---------->| Running |
43//! | | Cancel | | | |
44//! | |<----------------+ | | |
45//! +-----------------+ +---------------+--+ +-----------------+
46//! ^ |
47//! | |
48//! +---------+
49//! Restart
50//! ```
51//!
52//!
53//! A timer is initialized in the **stopped** state. A stopped timer can be
54//! **started** by the `start` operation, with an **expiry** time. After the
55//! `start` operation, the timer is in the **started** state. When the timer
56//! **expires**, the timer enters the **running** state and the handler is
57//! executed. After the handler has returned, the timer may enter the
58//! **started* or **stopped** state, depending on the return value of the
59//! handler. A timer in the **started** or **running** state may be **canceled**
60//! by the `cancel` operation. A timer that is cancelled enters the **stopped**
61//! state.
62//!
63//! A `cancel` or `restart` operation on a timer in the **running** state takes
64//! effect after the handler has returned and the timer has transitioned
65//! out of the **running** state.
66//!
67//! A `restart` operation on a timer in the **stopped** state is equivalent to a
68//! `start` operation.
69
70use super::ClockId;
71use crate::{prelude::*, time::Ktime, types::Opaque};
72use core::marker::PhantomData;
73use pin_init::PinInit;
74
75/// A timer backed by a C `struct hrtimer`.
76///
77/// # Invariants
78///
79/// * `self.timer` is initialized by `bindings::hrtimer_setup`.
80#[pin_data]
81#[repr(C)]
82pub struct HrTimer<T> {
83 #[pin]
84 timer: Opaque<bindings::hrtimer>,
85 mode: HrTimerMode,
86 _t: PhantomData<T>,
87}
88
89// SAFETY: Ownership of an `HrTimer` can be moved to other threads and
90// used/dropped from there.
91unsafe impl<T> Send for HrTimer<T> {}
92
93// SAFETY: Timer operations are locked on the C side, so it is safe to operate
94// on a timer from multiple threads.
95unsafe impl<T> Sync for HrTimer<T> {}
96
97impl<T> HrTimer<T> {
98 /// Return an initializer for a new timer instance.
99 pub fn new(mode: HrTimerMode, clock: ClockId) -> impl PinInit<Self>
100 where
101 T: HrTimerCallback,
102 {
103 pin_init!(Self {
104 // INVARIANT: We initialize `timer` with `hrtimer_setup` below.
105 timer <- Opaque::ffi_init(move |place: *mut bindings::hrtimer| {
106 // SAFETY: By design of `pin_init!`, `place` is a pointer to a
107 // live allocation. hrtimer_setup will initialize `place` and
108 // does not require `place` to be initialized prior to the call.
109 unsafe {
110 bindings::hrtimer_setup(
111 place,
112 Some(T::Pointer::run),
113 clock.into_c(),
114 mode.into_c(),
115 );
116 }
117 }),
118 mode: mode,
119 _t: PhantomData,
120 })
121 }
122
123 /// Get a pointer to the contained `bindings::hrtimer`.
124 ///
125 /// This function is useful to get access to the value without creating
126 /// intermediate references.
127 ///
128 /// # Safety
129 ///
130 /// `this` must point to a live allocation of at least the size of `Self`.
131 unsafe fn raw_get(this: *const Self) -> *mut bindings::hrtimer {
132 // SAFETY: The field projection to `timer` does not go out of bounds,
133 // because the caller of this function promises that `this` points to an
134 // allocation of at least the size of `Self`.
135 unsafe { Opaque::raw_get(core::ptr::addr_of!((*this).timer)) }
136 }
137
138 /// Cancel an initialized and potentially running timer.
139 ///
140 /// If the timer handler is running, this function will block until the
141 /// handler returns.
142 ///
143 /// Note that the timer might be started by a concurrent start operation. If
144 /// so, the timer might not be in the **stopped** state when this function
145 /// returns.
146 ///
147 /// Users of the `HrTimer` API would not usually call this method directly.
148 /// Instead they would use the safe [`HrTimerHandle::cancel`] on the handle
149 /// returned when the timer was started.
150 ///
151 /// This function is useful to get access to the value without creating
152 /// intermediate references.
153 ///
154 /// # Safety
155 ///
156 /// `this` must point to a valid `Self`.
157 pub(crate) unsafe fn raw_cancel(this: *const Self) -> bool {
158 // SAFETY: `this` points to an allocation of at least `HrTimer` size.
159 let c_timer_ptr = unsafe { HrTimer::raw_get(this) };
160
161 // If the handler is running, this will wait for the handler to return
162 // before returning.
163 // SAFETY: `c_timer_ptr` is initialized and valid. Synchronization is
164 // handled on the C side.
165 unsafe { bindings::hrtimer_cancel(c_timer_ptr) != 0 }
166 }
167}
168
169/// Implemented by pointer types that point to structs that contain a [`HrTimer`].
170///
171/// `Self` must be [`Sync`] because it is passed to timer callbacks in another
172/// thread of execution (hard or soft interrupt context).
173///
174/// Starting a timer returns a [`HrTimerHandle`] that can be used to manipulate
175/// the timer. Note that it is OK to call the start function repeatedly, and
176/// that more than one [`HrTimerHandle`] associated with a [`HrTimerPointer`] may
177/// exist. A timer can be manipulated through any of the handles, and a handle
178/// may represent a cancelled timer.
179pub trait HrTimerPointer: Sync + Sized {
180 /// A handle representing a started or restarted timer.
181 ///
182 /// If the timer is running or if the timer callback is executing when the
183 /// handle is dropped, the drop method of [`HrTimerHandle`] should not return
184 /// until the timer is stopped and the callback has completed.
185 ///
186 /// Note: When implementing this trait, consider that it is not unsafe to
187 /// leak the handle.
188 type TimerHandle: HrTimerHandle;
189
190 /// Start the timer with expiry after `expires` time units. If the timer was
191 /// already running, it is restarted with the new expiry time.
192 fn start(self, expires: Ktime) -> Self::TimerHandle;
193}
194
195/// Unsafe version of [`HrTimerPointer`] for situations where leaking the
196/// [`HrTimerHandle`] returned by `start` would be unsound. This is the case for
197/// stack allocated timers.
198///
199/// Typical implementers are pinned references such as [`Pin<&T>`].
200///
201/// # Safety
202///
203/// Implementers of this trait must ensure that instances of types implementing
204/// [`UnsafeHrTimerPointer`] outlives any associated [`HrTimerPointer::TimerHandle`]
205/// instances.
206pub unsafe trait UnsafeHrTimerPointer: Sync + Sized {
207 /// A handle representing a running timer.
208 ///
209 /// # Safety
210 ///
211 /// If the timer is running, or if the timer callback is executing when the
212 /// handle is dropped, the drop method of [`Self::TimerHandle`] must not return
213 /// until the timer is stopped and the callback has completed.
214 type TimerHandle: HrTimerHandle;
215
216 /// Start the timer after `expires` time units. If the timer was already
217 /// running, it is restarted at the new expiry time.
218 ///
219 /// # Safety
220 ///
221 /// Caller promises keep the timer structure alive until the timer is dead.
222 /// Caller can ensure this by not leaking the returned [`Self::TimerHandle`].
223 unsafe fn start(self, expires: Ktime) -> Self::TimerHandle;
224}
225
226/// A trait for stack allocated timers.
227///
228/// # Safety
229///
230/// Implementers must ensure that `start_scoped` does not return until the
231/// timer is dead and the timer handler is not running.
232pub unsafe trait ScopedHrTimerPointer {
233 /// Start the timer to run after `expires` time units and immediately
234 /// after call `f`. When `f` returns, the timer is cancelled.
235 fn start_scoped<T, F>(self, expires: Ktime, f: F) -> T
236 where
237 F: FnOnce() -> T;
238}
239
240// SAFETY: By the safety requirement of [`UnsafeHrTimerPointer`], dropping the
241// handle returned by [`UnsafeHrTimerPointer::start`] ensures that the timer is
242// killed.
243unsafe impl<T> ScopedHrTimerPointer for T
244where
245 T: UnsafeHrTimerPointer,
246{
247 fn start_scoped<U, F>(self, expires: Ktime, f: F) -> U
248 where
249 F: FnOnce() -> U,
250 {
251 // SAFETY: We drop the timer handle below before returning.
252 let handle = unsafe { UnsafeHrTimerPointer::start(self, expires) };
253 let t = f();
254 drop(handle);
255 t
256 }
257}
258
259/// Implemented by [`HrTimerPointer`] implementers to give the C timer callback a
260/// function to call.
261// This is split from `HrTimerPointer` to make it easier to specify trait bounds.
262pub trait RawHrTimerCallback {
263 /// Type of the parameter passed to [`HrTimerCallback::run`]. It may be
264 /// [`Self`], or a pointer type derived from [`Self`].
265 type CallbackTarget<'a>;
266
267 /// Callback to be called from C when timer fires.
268 ///
269 /// # Safety
270 ///
271 /// Only to be called by C code in the `hrtimer` subsystem. `this` must point
272 /// to the `bindings::hrtimer` structure that was used to start the timer.
273 unsafe extern "C" fn run(this: *mut bindings::hrtimer) -> bindings::hrtimer_restart;
274}
275
276/// Implemented by structs that can be the target of a timer callback.
277pub trait HrTimerCallback {
278 /// The type whose [`RawHrTimerCallback::run`] method will be invoked when
279 /// the timer expires.
280 type Pointer<'a>: RawHrTimerCallback;
281
282 /// Called by the timer logic when the timer fires.
283 fn run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart
284 where
285 Self: Sized;
286}
287
288/// A handle representing a potentially running timer.
289///
290/// More than one handle representing the same timer might exist.
291///
292/// # Safety
293///
294/// When dropped, the timer represented by this handle must be cancelled, if it
295/// is running. If the timer handler is running when the handle is dropped, the
296/// drop method must wait for the handler to return before returning.
297///
298/// Note: One way to satisfy the safety requirement is to call `Self::cancel` in
299/// the drop implementation for `Self.`
300pub unsafe trait HrTimerHandle {
301 /// Cancel the timer. If the timer is in the running state, block till the
302 /// handler has returned.
303 ///
304 /// Note that the timer might be started by a concurrent start operation. If
305 /// so, the timer might not be in the **stopped** state when this function
306 /// returns.
307 fn cancel(&mut self) -> bool;
308}
309
310/// Implemented by structs that contain timer nodes.
311///
312/// Clients of the timer API would usually safely implement this trait by using
313/// the [`crate::impl_has_hr_timer`] macro.
314///
315/// # Safety
316///
317/// Implementers of this trait must ensure that the implementer has a
318/// [`HrTimer`] field and that all trait methods are implemented according to
319/// their documentation. All the methods of this trait must operate on the same
320/// field.
321pub unsafe trait HasHrTimer<T> {
322 /// Return a pointer to the [`HrTimer`] within `Self`.
323 ///
324 /// This function is useful to get access to the value without creating
325 /// intermediate references.
326 ///
327 /// # Safety
328 ///
329 /// `this` must be a valid pointer.
330 unsafe fn raw_get_timer(this: *const Self) -> *const HrTimer<T>;
331
332 /// Return a pointer to the struct that is containing the [`HrTimer`] pointed
333 /// to by `ptr`.
334 ///
335 /// This function is useful to get access to the value without creating
336 /// intermediate references.
337 ///
338 /// # Safety
339 ///
340 /// `ptr` must point to a [`HrTimer<T>`] field in a struct of type `Self`.
341 unsafe fn timer_container_of(ptr: *mut HrTimer<T>) -> *mut Self
342 where
343 Self: Sized;
344
345 /// Get pointer to the contained `bindings::hrtimer` struct.
346 ///
347 /// This function is useful to get access to the value without creating
348 /// intermediate references.
349 ///
350 /// # Safety
351 ///
352 /// `this` must be a valid pointer.
353 unsafe fn c_timer_ptr(this: *const Self) -> *const bindings::hrtimer {
354 // SAFETY: `this` is a valid pointer to a `Self`.
355 let timer_ptr = unsafe { Self::raw_get_timer(this) };
356
357 // SAFETY: timer_ptr points to an allocation of at least `HrTimer` size.
358 unsafe { HrTimer::raw_get(timer_ptr) }
359 }
360
361 /// Start the timer contained in the `Self` pointed to by `self_ptr`. If
362 /// it is already running it is removed and inserted.
363 ///
364 /// # Safety
365 ///
366 /// - `this` must point to a valid `Self`.
367 /// - Caller must ensure that the pointee of `this` lives until the timer
368 /// fires or is canceled.
369 unsafe fn start(this: *const Self, expires: Ktime) {
370 // SAFETY: By function safety requirement, `this` is a valid `Self`.
371 unsafe {
372 bindings::hrtimer_start_range_ns(
373 Self::c_timer_ptr(this).cast_mut(),
374 expires.to_ns(),
375 0,
376 (*Self::raw_get_timer(this)).mode.into_c(),
377 );
378 }
379 }
380}
381
382/// Restart policy for timers.
383#[derive(Copy, Clone, PartialEq, Eq, Debug)]
384#[repr(u32)]
385pub enum HrTimerRestart {
386 /// Timer should not be restarted.
387 #[allow(clippy::unnecessary_cast)]
388 NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART as u32,
389 /// Timer should be restarted.
390 #[allow(clippy::unnecessary_cast)]
391 Restart = bindings::hrtimer_restart_HRTIMER_RESTART as u32,
392}
393
394impl HrTimerRestart {
395 fn into_c(self) -> bindings::hrtimer_restart {
396 self as bindings::hrtimer_restart
397 }
398}
399
400/// Operational mode of [`HrTimer`].
401// NOTE: Some of these have the same encoding on the C side, so we keep
402// `repr(Rust)` and convert elsewhere.
403#[derive(Clone, Copy, PartialEq, Eq, Debug)]
404pub enum HrTimerMode {
405 /// Timer expires at the given expiration time.
406 Absolute,
407 /// Timer expires after the given expiration time interpreted as a duration from now.
408 Relative,
409 /// Timer does not move between CPU cores.
410 Pinned,
411 /// Timer handler is executed in soft irq context.
412 Soft,
413 /// Timer handler is executed in hard irq context.
414 Hard,
415 /// Timer expires at the given expiration time.
416 /// Timer does not move between CPU cores.
417 AbsolutePinned,
418 /// Timer expires after the given expiration time interpreted as a duration from now.
419 /// Timer does not move between CPU cores.
420 RelativePinned,
421 /// Timer expires at the given expiration time.
422 /// Timer handler is executed in soft irq context.
423 AbsoluteSoft,
424 /// Timer expires after the given expiration time interpreted as a duration from now.
425 /// Timer handler is executed in soft irq context.
426 RelativeSoft,
427 /// Timer expires at the given expiration time.
428 /// Timer does not move between CPU cores.
429 /// Timer handler is executed in soft irq context.
430 AbsolutePinnedSoft,
431 /// Timer expires after the given expiration time interpreted as a duration from now.
432 /// Timer does not move between CPU cores.
433 /// Timer handler is executed in soft irq context.
434 RelativePinnedSoft,
435 /// Timer expires at the given expiration time.
436 /// Timer handler is executed in hard irq context.
437 AbsoluteHard,
438 /// Timer expires after the given expiration time interpreted as a duration from now.
439 /// Timer handler is executed in hard irq context.
440 RelativeHard,
441 /// Timer expires at the given expiration time.
442 /// Timer does not move between CPU cores.
443 /// Timer handler is executed in hard irq context.
444 AbsolutePinnedHard,
445 /// Timer expires after the given expiration time interpreted as a duration from now.
446 /// Timer does not move between CPU cores.
447 /// Timer handler is executed in hard irq context.
448 RelativePinnedHard,
449}
450
451impl HrTimerMode {
452 fn into_c(self) -> bindings::hrtimer_mode {
453 use bindings::*;
454 match self {
455 HrTimerMode::Absolute => hrtimer_mode_HRTIMER_MODE_ABS,
456 HrTimerMode::Relative => hrtimer_mode_HRTIMER_MODE_REL,
457 HrTimerMode::Pinned => hrtimer_mode_HRTIMER_MODE_PINNED,
458 HrTimerMode::Soft => hrtimer_mode_HRTIMER_MODE_SOFT,
459 HrTimerMode::Hard => hrtimer_mode_HRTIMER_MODE_HARD,
460 HrTimerMode::AbsolutePinned => hrtimer_mode_HRTIMER_MODE_ABS_PINNED,
461 HrTimerMode::RelativePinned => hrtimer_mode_HRTIMER_MODE_REL_PINNED,
462 HrTimerMode::AbsoluteSoft => hrtimer_mode_HRTIMER_MODE_ABS_SOFT,
463 HrTimerMode::RelativeSoft => hrtimer_mode_HRTIMER_MODE_REL_SOFT,
464 HrTimerMode::AbsolutePinnedSoft => hrtimer_mode_HRTIMER_MODE_ABS_PINNED_SOFT,
465 HrTimerMode::RelativePinnedSoft => hrtimer_mode_HRTIMER_MODE_REL_PINNED_SOFT,
466 HrTimerMode::AbsoluteHard => hrtimer_mode_HRTIMER_MODE_ABS_HARD,
467 HrTimerMode::RelativeHard => hrtimer_mode_HRTIMER_MODE_REL_HARD,
468 HrTimerMode::AbsolutePinnedHard => hrtimer_mode_HRTIMER_MODE_ABS_PINNED_HARD,
469 HrTimerMode::RelativePinnedHard => hrtimer_mode_HRTIMER_MODE_REL_PINNED_HARD,
470 }
471 }
472}
473
474/// Use to implement the [`HasHrTimer<T>`] trait.
475///
476/// See [`module`] documentation for an example.
477///
478/// [`module`]: crate::time::hrtimer
479#[macro_export]
480macro_rules! impl_has_hr_timer {
481 (
482 impl$({$($generics:tt)*})?
483 HasHrTimer<$timer_type:ty>
484 for $self:ty
485 { self.$field:ident }
486 $($rest:tt)*
487 ) => {
488 // SAFETY: This implementation of `raw_get_timer` only compiles if the
489 // field has the right type.
490 unsafe impl$(<$($generics)*>)? $crate::time::hrtimer::HasHrTimer<$timer_type> for $self {
491
492 #[inline]
493 unsafe fn raw_get_timer(
494 this: *const Self,
495 ) -> *const $crate::time::hrtimer::HrTimer<$timer_type> {
496 // SAFETY: The caller promises that the pointer is not dangling.
497 unsafe { ::core::ptr::addr_of!((*this).$field) }
498 }
499
500 #[inline]
501 unsafe fn timer_container_of(
502 ptr: *mut $crate::time::hrtimer::HrTimer<$timer_type>,
503 ) -> *mut Self {
504 // SAFETY: As per the safety requirement of this function, `ptr`
505 // is pointing inside a `$timer_type`.
506 unsafe { ::kernel::container_of!(ptr, $timer_type, $field).cast_mut() }
507 }
508 }
509 }
510}
511
512mod arc;
513pub use arc::ArcHrTimerHandle;
514mod pin;
515pub use pin::PinHrTimerHandle;
516mod pin_mut;
517pub use pin_mut::PinMutHrTimerHandle;
518// `box` is a reserved keyword, so prefix with `t` for timer
519mod tbox;
520pub use tbox::BoxHrTimerHandle;