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