xref: /linux/rust/kernel/time/hrtimer/pin_mut.rs (revision ec7714e4947909190ffb3041a03311a975350fe0)
1042b0c79SAndreas Hindborg // SPDX-License-Identifier: GPL-2.0
2042b0c79SAndreas Hindborg 
3042b0c79SAndreas Hindborg use super::{
4*1116f0c5SFUJITA Tomonori     HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, Ktime, RawHrTimerCallback,
5*1116f0c5SFUJITA Tomonori     UnsafeHrTimerPointer,
6042b0c79SAndreas Hindborg };
7042b0c79SAndreas Hindborg use core::{marker::PhantomData, pin::Pin, ptr::NonNull};
8042b0c79SAndreas Hindborg 
9042b0c79SAndreas Hindborg /// A handle for a `Pin<&mut HasHrTimer>`. When the handle exists, the timer might
10042b0c79SAndreas Hindborg /// be running.
11042b0c79SAndreas Hindborg pub struct PinMutHrTimerHandle<'a, T>
12042b0c79SAndreas Hindborg where
13042b0c79SAndreas Hindborg     T: HasHrTimer<T>,
14042b0c79SAndreas Hindborg {
15042b0c79SAndreas Hindborg     pub(crate) inner: NonNull<T>,
16042b0c79SAndreas Hindborg     _p: PhantomData<&'a mut T>,
17042b0c79SAndreas Hindborg }
18042b0c79SAndreas Hindborg 
19042b0c79SAndreas Hindborg // SAFETY: We cancel the timer when the handle is dropped. The implementation of
20042b0c79SAndreas Hindborg // the `cancel` method will block if the timer handler is running.
21042b0c79SAndreas Hindborg unsafe impl<'a, T> HrTimerHandle for PinMutHrTimerHandle<'a, T>
22042b0c79SAndreas Hindborg where
23042b0c79SAndreas Hindborg     T: HasHrTimer<T>,
24042b0c79SAndreas Hindborg {
cancel(&mut self) -> bool25042b0c79SAndreas Hindborg     fn cancel(&mut self) -> bool {
26042b0c79SAndreas Hindborg         let self_ptr = self.inner.as_ptr();
27042b0c79SAndreas Hindborg 
28042b0c79SAndreas Hindborg         // SAFETY: As we got `self_ptr` from a reference above, it must point to
29042b0c79SAndreas Hindborg         // a valid `T`.
30042b0c79SAndreas Hindborg         let timer_ptr = unsafe { <T as HasHrTimer<T>>::raw_get_timer(self_ptr) };
31042b0c79SAndreas Hindborg 
32042b0c79SAndreas Hindborg         // SAFETY: As `timer_ptr` is derived from a reference, it must point to
33042b0c79SAndreas Hindborg         // a valid and initialized `HrTimer`.
34042b0c79SAndreas Hindborg         unsafe { HrTimer::<T>::raw_cancel(timer_ptr) }
35042b0c79SAndreas Hindborg     }
36042b0c79SAndreas Hindborg }
37042b0c79SAndreas Hindborg 
38042b0c79SAndreas Hindborg impl<'a, T> Drop for PinMutHrTimerHandle<'a, T>
39042b0c79SAndreas Hindborg where
40042b0c79SAndreas Hindborg     T: HasHrTimer<T>,
41042b0c79SAndreas Hindborg {
drop(&mut self)42042b0c79SAndreas Hindborg     fn drop(&mut self) {
43042b0c79SAndreas Hindborg         self.cancel();
44042b0c79SAndreas Hindborg     }
45042b0c79SAndreas Hindborg }
46042b0c79SAndreas Hindborg 
47042b0c79SAndreas Hindborg // SAFETY: We capture the lifetime of `Self` when we create a
48042b0c79SAndreas Hindborg // `PinMutHrTimerHandle`, so `Self` will outlive the handle.
49042b0c79SAndreas Hindborg unsafe impl<'a, T> UnsafeHrTimerPointer for Pin<&'a mut T>
50042b0c79SAndreas Hindborg where
51042b0c79SAndreas Hindborg     T: Send + Sync,
52042b0c79SAndreas Hindborg     T: HasHrTimer<T>,
53042b0c79SAndreas Hindborg     T: HrTimerCallback<Pointer<'a> = Self>,
54042b0c79SAndreas Hindborg {
55042b0c79SAndreas Hindborg     type TimerHandle = PinMutHrTimerHandle<'a, T>;
56042b0c79SAndreas Hindborg 
start(mut self, expires: Ktime) -> Self::TimerHandle57042b0c79SAndreas Hindborg     unsafe fn start(mut self, expires: Ktime) -> Self::TimerHandle {
58042b0c79SAndreas Hindborg         // SAFETY:
59042b0c79SAndreas Hindborg         // - We promise not to move out of `self`. We only pass `self`
60042b0c79SAndreas Hindborg         //   back to the caller as a `Pin<&mut self>`.
61042b0c79SAndreas Hindborg         // - The return value of `get_unchecked_mut` is guaranteed not to be null.
62042b0c79SAndreas Hindborg         let self_ptr = unsafe { NonNull::new_unchecked(self.as_mut().get_unchecked_mut()) };
63042b0c79SAndreas Hindborg 
64042b0c79SAndreas Hindborg         // SAFETY:
65042b0c79SAndreas Hindborg         //  - As we derive `self_ptr` from a reference above, it must point to a
66042b0c79SAndreas Hindborg         //    valid `T`.
67042b0c79SAndreas Hindborg         //  - We keep `self` alive by wrapping it in a handle below.
68042b0c79SAndreas Hindborg         unsafe { T::start(self_ptr.as_ptr(), expires) };
69042b0c79SAndreas Hindborg 
70042b0c79SAndreas Hindborg         PinMutHrTimerHandle {
71042b0c79SAndreas Hindborg             inner: self_ptr,
72042b0c79SAndreas Hindborg             _p: PhantomData,
73042b0c79SAndreas Hindborg         }
74042b0c79SAndreas Hindborg     }
75042b0c79SAndreas Hindborg }
76042b0c79SAndreas Hindborg 
77042b0c79SAndreas Hindborg impl<'a, T> RawHrTimerCallback for Pin<&'a mut T>
78042b0c79SAndreas Hindborg where
79042b0c79SAndreas Hindborg     T: HasHrTimer<T>,
80042b0c79SAndreas Hindborg     T: HrTimerCallback<Pointer<'a> = Self>,
81042b0c79SAndreas Hindborg {
82042b0c79SAndreas Hindborg     type CallbackTarget<'b> = Self;
83042b0c79SAndreas Hindborg 
run(ptr: *mut bindings::hrtimer) -> bindings::hrtimer_restart84042b0c79SAndreas Hindborg     unsafe extern "C" fn run(ptr: *mut bindings::hrtimer) -> bindings::hrtimer_restart {
85042b0c79SAndreas Hindborg         // `HrTimer` is `repr(C)`
86042b0c79SAndreas Hindborg         let timer_ptr = ptr as *mut HrTimer<T>;
87042b0c79SAndreas Hindborg 
88042b0c79SAndreas Hindborg         // SAFETY: By the safety requirement of this function, `timer_ptr`
89042b0c79SAndreas Hindborg         // points to a `HrTimer<T>` contained in an `T`.
90042b0c79SAndreas Hindborg         let receiver_ptr = unsafe { T::timer_container_of(timer_ptr) };
91042b0c79SAndreas Hindborg 
92042b0c79SAndreas Hindborg         // SAFETY:
93042b0c79SAndreas Hindborg         //  - By the safety requirement of this function, `timer_ptr`
94042b0c79SAndreas Hindborg         //    points to a `HrTimer<T>` contained in an `T`.
95042b0c79SAndreas Hindborg         //  - As per the safety requirements of the trait `HrTimerHandle`, the
96042b0c79SAndreas Hindborg         //    `PinMutHrTimerHandle` associated with this timer is guaranteed to
97042b0c79SAndreas Hindborg         //    be alive until this method returns. That handle borrows the `T`
98042b0c79SAndreas Hindborg         //    behind `receiver_ptr` mutably thus guaranteeing the validity of
99042b0c79SAndreas Hindborg         //    the reference created below.
100042b0c79SAndreas Hindborg         let receiver_ref = unsafe { &mut *receiver_ptr };
101042b0c79SAndreas Hindborg 
102042b0c79SAndreas Hindborg         // SAFETY: `receiver_ref` only exists as pinned, so it is safe to pin it
103042b0c79SAndreas Hindborg         // here.
104042b0c79SAndreas Hindborg         let receiver_pin = unsafe { Pin::new_unchecked(receiver_ref) };
105042b0c79SAndreas Hindborg 
106042b0c79SAndreas Hindborg         T::run(receiver_pin).into_c()
107042b0c79SAndreas Hindborg     }
108042b0c79SAndreas Hindborg }
109