FILE
pin.rs
File preview with syntax highlighting.
linux-6.19.14/rust/kernel/time/hrtimer/pin.rs
1// SPDX-License-Identifier: GPL-2.0 2 3use super::HasHrTimer; 4use super::HrTimer; 5use super::HrTimerCallback; 6use super::HrTimerCallbackContext; 7use super::HrTimerHandle; 8use super::HrTimerMode; 9use super::RawHrTimerCallback; 10use super::UnsafeHrTimerPointer; 11use core::pin::Pin; 12 13/// A handle for a `Pin<&HasHrTimer>`. When the handle exists, the timer might be 14/// running. 15pub struct PinHrTimerHandle<'a, T> 16where 17 T: HasHrTimer<T>, 18{ 19 pub(crate) inner: Pin<&'a T>, 20} 21 22// SAFETY: We cancel the timer when the handle is dropped. The implementation of 23// the `cancel` method will block if the timer handler is running. 24unsafe impl<'a, T> HrTimerHandle for PinHrTimerHandle<'a, T> 25where 26 T: HasHrTimer<T>, 27{ 28 fn cancel(&mut self) -> bool { 29 let self_ptr: *const T = self.inner.get_ref(); 30 31 // SAFETY: As we got `self_ptr` from a reference above, it must point to 32 // a valid `T`. 33 let timer_ptr = unsafe { <T as HasHrTimer<T>>::raw_get_timer(self_ptr) }; 34 35 // SAFETY: As `timer_ptr` is derived from a reference, it must point to 36 // a valid and initialized `HrTimer`. 37 unsafe { HrTimer::<T>::raw_cancel(timer_ptr) } 38 } 39} 40 41impl<'a, T> Drop for PinHrTimerHandle<'a, T> 42where 43 T: HasHrTimer<T>, 44{ 45 fn drop(&mut self) { 46 self.cancel(); 47 } 48} 49 50// SAFETY: We capture the lifetime of `Self` when we create a `PinHrTimerHandle`, 51// so `Self` will outlive the handle. 52unsafe impl<'a, T> UnsafeHrTimerPointer for Pin<&'a T> 53where 54 T: Send + Sync, 55 T: HasHrTimer<T>, 56 T: HrTimerCallback<Pointer<'a> = Self>, 57{ 58 type TimerMode = <T as HasHrTimer<T>>::TimerMode; 59 type TimerHandle = PinHrTimerHandle<'a, T>; 60 61 unsafe fn start( 62 self, 63 expires: <<T as HasHrTimer<T>>::TimerMode as HrTimerMode>::Expires, 64 ) -> Self::TimerHandle { 65 // Cast to pointer 66 let self_ptr: *const T = self.get_ref(); 67 68 // SAFETY: 69 // - As we derive `self_ptr` from a reference above, it must point to a 70 // valid `T`. 71 // - We keep `self` alive by wrapping it in a handle below. 72 unsafe { T::start(self_ptr, expires) }; 73 74 PinHrTimerHandle { inner: self } 75 } 76} 77 78impl<'a, T> RawHrTimerCallback for Pin<&'a T> 79where 80 T: HasHrTimer<T>, 81 T: HrTimerCallback<Pointer<'a> = Self>, 82{ 83 type CallbackTarget<'b> = Self; 84 85 unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrtimer_restart { 86 // `HrTimer` is `repr(C)` 87 let timer_ptr = ptr.cast::<HrTimer<T>>(); 88 89 // SAFETY: By the safety requirement of this function, `timer_ptr` 90 // points to a `HrTimer<T>` contained in an `T`. 91 let receiver_ptr = unsafe { T::timer_container_of(timer_ptr) }; 92 93 // SAFETY: 94 // - By the safety requirement of this function, `timer_ptr` 95 // points to a `HrTimer<T>` contained in an `T`. 96 // - As per the safety requirements of the trait `HrTimerHandle`, the 97 // `PinHrTimerHandle` associated with this timer is guaranteed to 98 // be alive until this method returns. That handle borrows the `T` 99 // behind `receiver_ptr`, thus guaranteeing the validity of 100 // the reference created below. 101 let receiver_ref = unsafe { &*receiver_ptr }; 102 103 // SAFETY: `receiver_ref` only exists as pinned, so it is safe to pin it 104 // here. 105 let receiver_pin = unsafe { Pin::new_unchecked(receiver_ref) }; 106 107 // SAFETY: 108 // - By C API contract `timer_ptr` is the pointer that we passed when queuing the timer, so 109 // it is a valid pointer to a `HrTimer<T>` embedded in a `T`. 110 // - We are within `RawHrTimerCallback::run` 111 let context = unsafe { HrTimerCallbackContext::from_raw(timer_ptr) }; 112 113 T::run(receiver_pin, context).into_c() 114 } 115}
~/
Read-only file preview.