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::*, time::Ktime, types::Opaque}; 72 use core::marker::PhantomData; 73 use 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)] 82 pub 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. 91 unsafe 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. 95 unsafe impl<T> Sync for HrTimer<T> {} 96 97 impl<T> HrTimer<T> { 98 /// Return an initializer for a new timer instance. new(mode: HrTimerMode, clock: ClockId) -> impl PinInit<Self> where T: HrTimerCallback,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`. raw_get(this: *const Self) -> *mut bindings::hrtimer131 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`. raw_cancel(this: *const Self) -> bool157 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. 179 pub 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. start(self, expires: Ktime) -> Self::TimerHandle192 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. 206 pub 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`]. start(self, expires: Ktime) -> Self::TimerHandle223 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. 232 pub 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. start_scoped<T, F>(self, expires: Ktime, f: F) -> T where F: FnOnce() -> T235 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. 243 unsafe impl<T> ScopedHrTimerPointer for T 244 where 245 T: UnsafeHrTimerPointer, 246 { start_scoped<U, F>(self, expires: Ktime, f: F) -> U where F: FnOnce() -> U,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. 262 pub 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. run(this: *mut bindings::hrtimer) -> bindings::hrtimer_restart273 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. 277 pub 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. run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart where Self: Sized283 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.` 300 pub 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. cancel(&mut self) -> bool307 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. 321 pub 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. raw_get_timer(this: *const Self) -> *const HrTimer<T>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`. timer_container_of(ptr: *mut HrTimer<T>) -> *mut Self where Self: Sized341 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. c_timer_ptr(this: *const Self) -> *const bindings::hrtimer353 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. start(this: *const Self, expires: Ktime)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)] 385 pub 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 394 impl HrTimerRestart { into_c(self) -> bindings::hrtimer_restart395 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)] 404 pub 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 451 impl HrTimerMode { into_c(self) -> bindings::hrtimer_mode452 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] 480 macro_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 512 mod arc; 513 pub use arc::ArcHrTimerHandle; 514 mod pin; 515 pub use pin::PinHrTimerHandle; 516 mod pin_mut; 517 pub use pin_mut::PinMutHrTimerHandle; 518 // `box` is a reserved keyword, so prefix with `t` for timer 519 mod tbox; 520 pub use tbox::BoxHrTimerHandle; 521