xref: /linux/rust/kernel/types.rs (revision 7255fcc80d4b525cc10cfaaf7f485830d4ed2000)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Kernel types.
4 
5 use crate::init::{self, PinInit};
6 use alloc::boxed::Box;
7 use core::{
8     cell::UnsafeCell,
9     marker::{PhantomData, PhantomPinned},
10     mem::MaybeUninit,
11     ops::{Deref, DerefMut},
12     ptr::NonNull,
13 };
14 
15 /// Used to transfer ownership to and from foreign (non-Rust) languages.
16 ///
17 /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
18 /// later may be transferred back to Rust by calling [`Self::from_foreign`].
19 ///
20 /// This trait is meant to be used in cases when Rust objects are stored in C objects and
21 /// eventually "freed" back to Rust.
22 pub trait ForeignOwnable: Sized {
23     /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
24     /// [`ForeignOwnable::from_foreign`].
25     type Borrowed<'a>;
26 
27     /// Converts a Rust-owned object to a foreign-owned one.
28     ///
29     /// The foreign representation is a pointer to void.
30     fn into_foreign(self) -> *const core::ffi::c_void;
31 
32     /// Borrows a foreign-owned object.
33     ///
34     /// # Safety
35     ///
36     /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
37     /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
38     unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>;
39 
40     /// Converts a foreign-owned object back to a Rust-owned one.
41     ///
42     /// # Safety
43     ///
44     /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
45     /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
46     /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
47     /// this object must have been dropped.
48     unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self;
49 
50     /// Tries to convert a foreign-owned object back to a Rust-owned one.
51     ///
52     /// A convenience wrapper over [`ForeignOwnable::from_foreign`] that returns [`None`] if `ptr`
53     /// is null.
54     ///
55     /// # Safety
56     ///
57     /// `ptr` must either be null or satisfy the safety requirements for
58     /// [`ForeignOwnable::from_foreign`].
59     unsafe fn try_from_foreign(ptr: *const core::ffi::c_void) -> Option<Self> {
60         if ptr.is_null() {
61             None
62         } else {
63             // SAFETY: Since `ptr` is not null here, then `ptr` satisfies the safety requirements
64             // of `from_foreign` given the safety requirements of this function.
65             unsafe { Some(Self::from_foreign(ptr)) }
66         }
67     }
68 }
69 
70 impl<T: 'static> ForeignOwnable for Box<T> {
71     type Borrowed<'a> = &'a T;
72 
73     fn into_foreign(self) -> *const core::ffi::c_void {
74         Box::into_raw(self) as _
75     }
76 
77     unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T {
78         // SAFETY: The safety requirements for this function ensure that the object is still alive,
79         // so it is safe to dereference the raw pointer.
80         // The safety requirements of `from_foreign` also ensure that the object remains alive for
81         // the lifetime of the returned value.
82         unsafe { &*ptr.cast() }
83     }
84 
85     unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
86         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
87         // call to `Self::into_foreign`.
88         unsafe { Box::from_raw(ptr as _) }
89     }
90 }
91 
92 impl ForeignOwnable for () {
93     type Borrowed<'a> = ();
94 
95     fn into_foreign(self) -> *const core::ffi::c_void {
96         core::ptr::NonNull::dangling().as_ptr()
97     }
98 
99     unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a> {}
100 
101     unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {}
102 }
103 
104 /// Runs a cleanup function/closure when dropped.
105 ///
106 /// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running.
107 ///
108 /// # Examples
109 ///
110 /// In the example below, we have multiple exit paths and we want to log regardless of which one is
111 /// taken:
112 ///
113 /// ```
114 /// # use kernel::types::ScopeGuard;
115 /// fn example1(arg: bool) {
116 ///     let _log = ScopeGuard::new(|| pr_info!("example1 completed\n"));
117 ///
118 ///     if arg {
119 ///         return;
120 ///     }
121 ///
122 ///     pr_info!("Do something...\n");
123 /// }
124 ///
125 /// # example1(false);
126 /// # example1(true);
127 /// ```
128 ///
129 /// In the example below, we want to log the same message on all early exits but a different one on
130 /// the main exit path:
131 ///
132 /// ```
133 /// # use kernel::types::ScopeGuard;
134 /// fn example2(arg: bool) {
135 ///     let log = ScopeGuard::new(|| pr_info!("example2 returned early\n"));
136 ///
137 ///     if arg {
138 ///         return;
139 ///     }
140 ///
141 ///     // (Other early returns...)
142 ///
143 ///     log.dismiss();
144 ///     pr_info!("example2 no early return\n");
145 /// }
146 ///
147 /// # example2(false);
148 /// # example2(true);
149 /// ```
150 ///
151 /// In the example below, we need a mutable object (the vector) to be accessible within the log
152 /// function, so we wrap it in the [`ScopeGuard`]:
153 ///
154 /// ```
155 /// # use kernel::types::ScopeGuard;
156 /// fn example3(arg: bool) -> Result {
157 ///     let mut vec =
158 ///         ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {} elements\n", v.len()));
159 ///
160 ///     vec.try_push(10u8)?;
161 ///     if arg {
162 ///         return Ok(());
163 ///     }
164 ///     vec.try_push(20u8)?;
165 ///     Ok(())
166 /// }
167 ///
168 /// # assert_eq!(example3(false), Ok(()));
169 /// # assert_eq!(example3(true), Ok(()));
170 /// ```
171 ///
172 /// # Invariants
173 ///
174 /// The value stored in the struct is nearly always `Some(_)`, except between
175 /// [`ScopeGuard::dismiss`] and [`ScopeGuard::drop`]: in this case, it will be `None` as the value
176 /// will have been returned to the caller. Since  [`ScopeGuard::dismiss`] consumes the guard,
177 /// callers won't be able to use it anymore.
178 pub struct ScopeGuard<T, F: FnOnce(T)>(Option<(T, F)>);
179 
180 impl<T, F: FnOnce(T)> ScopeGuard<T, F> {
181     /// Creates a new guarded object wrapping the given data and with the given cleanup function.
182     pub fn new_with_data(data: T, cleanup_func: F) -> Self {
183         // INVARIANT: The struct is being initialised with `Some(_)`.
184         Self(Some((data, cleanup_func)))
185     }
186 
187     /// Prevents the cleanup function from running and returns the guarded data.
188     pub fn dismiss(mut self) -> T {
189         // INVARIANT: This is the exception case in the invariant; it is not visible to callers
190         // because this function consumes `self`.
191         self.0.take().unwrap().0
192     }
193 }
194 
195 impl ScopeGuard<(), fn(())> {
196     /// Creates a new guarded object with the given cleanup function.
197     pub fn new(cleanup: impl FnOnce()) -> ScopeGuard<(), impl FnOnce(())> {
198         ScopeGuard::new_with_data((), move |_| cleanup())
199     }
200 }
201 
202 impl<T, F: FnOnce(T)> Deref for ScopeGuard<T, F> {
203     type Target = T;
204 
205     fn deref(&self) -> &T {
206         // The type invariants guarantee that `unwrap` will succeed.
207         &self.0.as_ref().unwrap().0
208     }
209 }
210 
211 impl<T, F: FnOnce(T)> DerefMut for ScopeGuard<T, F> {
212     fn deref_mut(&mut self) -> &mut T {
213         // The type invariants guarantee that `unwrap` will succeed.
214         &mut self.0.as_mut().unwrap().0
215     }
216 }
217 
218 impl<T, F: FnOnce(T)> Drop for ScopeGuard<T, F> {
219     fn drop(&mut self) {
220         // Run the cleanup function if one is still present.
221         if let Some((data, cleanup)) = self.0.take() {
222             cleanup(data)
223         }
224     }
225 }
226 
227 /// Stores an opaque value.
228 ///
229 /// This is meant to be used with FFI objects that are never interpreted by Rust code.
230 #[repr(transparent)]
231 pub struct Opaque<T> {
232     value: UnsafeCell<MaybeUninit<T>>,
233     _pin: PhantomPinned,
234 }
235 
236 impl<T> Opaque<T> {
237     /// Creates a new opaque value.
238     pub const fn new(value: T) -> Self {
239         Self {
240             value: UnsafeCell::new(MaybeUninit::new(value)),
241             _pin: PhantomPinned,
242         }
243     }
244 
245     /// Creates an uninitialised value.
246     pub const fn uninit() -> Self {
247         Self {
248             value: UnsafeCell::new(MaybeUninit::uninit()),
249             _pin: PhantomPinned,
250         }
251     }
252 
253     /// Creates a pin-initializer from the given initializer closure.
254     ///
255     /// The returned initializer calls the given closure with the pointer to the inner `T` of this
256     /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it.
257     ///
258     /// This function is safe, because the `T` inside of an `Opaque` is allowed to be
259     /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs
260     /// to verify at that point that the inner value is valid.
261     pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit<Self> {
262         // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully
263         // initialize the `T`.
264         unsafe {
265             init::pin_init_from_closure::<_, ::core::convert::Infallible>(move |slot| {
266                 init_func(Self::raw_get(slot));
267                 Ok(())
268             })
269         }
270     }
271 
272     /// Returns a raw pointer to the opaque data.
273     pub fn get(&self) -> *mut T {
274         UnsafeCell::get(&self.value).cast::<T>()
275     }
276 
277     /// Gets the value behind `this`.
278     ///
279     /// This function is useful to get access to the value without creating intermediate
280     /// references.
281     pub const fn raw_get(this: *const Self) -> *mut T {
282         UnsafeCell::raw_get(this.cast::<UnsafeCell<MaybeUninit<T>>>()).cast::<T>()
283     }
284 }
285 
286 /// Types that are _always_ reference counted.
287 ///
288 /// It allows such types to define their own custom ref increment and decrement functions.
289 /// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
290 /// [`ARef<T>`].
291 ///
292 /// This is usually implemented by wrappers to existing structures on the C side of the code. For
293 /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
294 /// instances of a type.
295 ///
296 /// # Safety
297 ///
298 /// Implementers must ensure that increments to the reference count keep the object alive in memory
299 /// at least until matching decrements are performed.
300 ///
301 /// Implementers must also ensure that all instances are reference-counted. (Otherwise they
302 /// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
303 /// alive.)
304 pub unsafe trait AlwaysRefCounted {
305     /// Increments the reference count on the object.
306     fn inc_ref(&self);
307 
308     /// Decrements the reference count on the object.
309     ///
310     /// Frees the object when the count reaches zero.
311     ///
312     /// # Safety
313     ///
314     /// Callers must ensure that there was a previous matching increment to the reference count,
315     /// and that the object is no longer used after its reference count is decremented (as it may
316     /// result in the object being freed), unless the caller owns another increment on the refcount
317     /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
318     /// [`AlwaysRefCounted::dec_ref`] once).
319     unsafe fn dec_ref(obj: NonNull<Self>);
320 }
321 
322 /// An owned reference to an always-reference-counted object.
323 ///
324 /// The object's reference count is automatically decremented when an instance of [`ARef`] is
325 /// dropped. It is also automatically incremented when a new instance is created via
326 /// [`ARef::clone`].
327 ///
328 /// # Invariants
329 ///
330 /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
331 /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
332 pub struct ARef<T: AlwaysRefCounted> {
333     ptr: NonNull<T>,
334     _p: PhantomData<T>,
335 }
336 
337 // SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
338 // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
339 // `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
340 // mutable reference, for example, when the reference count reaches zero and `T` is dropped.
341 unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {}
342 
343 // SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
344 // because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
345 // it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
346 // `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
347 // example, when the reference count reaches zero and `T` is dropped.
348 unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
349 
350 impl<T: AlwaysRefCounted> ARef<T> {
351     /// Creates a new instance of [`ARef`].
352     ///
353     /// It takes over an increment of the reference count on the underlying object.
354     ///
355     /// # Safety
356     ///
357     /// Callers must ensure that the reference count was incremented at least once, and that they
358     /// are properly relinquishing one increment. That is, if there is only one increment, callers
359     /// must not use the underlying object anymore -- it is only safe to do so via the newly
360     /// created [`ARef`].
361     pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
362         // INVARIANT: The safety requirements guarantee that the new instance now owns the
363         // increment on the refcount.
364         Self {
365             ptr,
366             _p: PhantomData,
367         }
368     }
369 }
370 
371 impl<T: AlwaysRefCounted> Clone for ARef<T> {
372     fn clone(&self) -> Self {
373         self.inc_ref();
374         // SAFETY: We just incremented the refcount above.
375         unsafe { Self::from_raw(self.ptr) }
376     }
377 }
378 
379 impl<T: AlwaysRefCounted> Deref for ARef<T> {
380     type Target = T;
381 
382     fn deref(&self) -> &Self::Target {
383         // SAFETY: The type invariants guarantee that the object is valid.
384         unsafe { self.ptr.as_ref() }
385     }
386 }
387 
388 impl<T: AlwaysRefCounted> From<&T> for ARef<T> {
389     fn from(b: &T) -> Self {
390         b.inc_ref();
391         // SAFETY: We just incremented the refcount above.
392         unsafe { Self::from_raw(NonNull::from(b)) }
393     }
394 }
395 
396 impl<T: AlwaysRefCounted> Drop for ARef<T> {
397     fn drop(&mut self) {
398         // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
399         // decrement.
400         unsafe { T::dec_ref(self.ptr) };
401     }
402 }
403 
404 /// A sum type that always holds either a value of type `L` or `R`.
405 pub enum Either<L, R> {
406     /// Constructs an instance of [`Either`] containing a value of type `L`.
407     Left(L),
408 
409     /// Constructs an instance of [`Either`] containing a value of type `R`.
410     Right(R),
411 }
412