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 70 use super::ClockId; 71 use crate::{prelude::*, types::Opaque}; 72 use core::marker::PhantomData; 73 use 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)] 79 pub struct Ktime { 80 inner: bindings::ktime_t, 81 } 82 83 impl Ktime { 84 /// Returns the number of nanoseconds. 85 #[inline] to_ns(self) -> i6486 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)] 98 pub 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. 107 unsafe 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. 111 unsafe impl<T> Sync for HrTimer<T> {} 112 113 impl<T> HrTimer<T> { 114 /// Return an initializer for a new timer instance. new(mode: HrTimerMode, clock: ClockId) -> impl PinInit<Self> where T: HrTimerCallback,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`. raw_get(this: *const Self) -> *mut bindings::hrtimer147 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`. raw_cancel(this: *const Self) -> bool173 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. 195 pub 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. start(self, expires: Ktime) -> Self::TimerHandle208 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. 222 pub 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`]. start(self, expires: Ktime) -> Self::TimerHandle239 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. 248 pub 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. start_scoped<T, F>(self, expires: Ktime, f: F) -> T where F: FnOnce() -> T251 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. 259 unsafe impl<T> ScopedHrTimerPointer for T 260 where 261 T: UnsafeHrTimerPointer, 262 { start_scoped<U, F>(self, expires: Ktime, f: F) -> U where F: FnOnce() -> U,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. 278 pub 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. run(this: *mut bindings::hrtimer) -> bindings::hrtimer_restart289 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. 293 pub 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. run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart where Self: Sized299 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.` 316 pub 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. cancel(&mut self) -> bool323 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. 337 pub 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. raw_get_timer(this: *const Self) -> *const HrTimer<T>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`. timer_container_of(ptr: *mut HrTimer<T>) -> *mut Self where Self: Sized357 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. c_timer_ptr(this: *const Self) -> *const bindings::hrtimer369 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. start(this: *const Self, expires: Ktime)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)] 401 pub 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 408 impl HrTimerRestart { into_c(self) -> bindings::hrtimer_restart409 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)] 418 pub 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 465 impl HrTimerMode { into_c(self) -> bindings::hrtimer_mode466 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] 494 macro_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 526 mod arc; 527 pub use arc::ArcHrTimerHandle; 528 mod pin; 529 pub use pin::PinHrTimerHandle; 530 mod pin_mut; 531 pub use pin_mut::PinMutHrTimerHandle; 532 // `box` is a reserved keyword, so prefix with `t` for timer 533 mod tbox; 534 pub use tbox::BoxHrTimerHandle; 535