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