xref: /linux/rust/kernel/init.rs (revision 784faa8eca8270671e0ed6d9d21f04bbb80fc5f7)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Extensions to the [`pin-init`] crate.
4 //!
5 //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential
6 //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move.
7 //!
8 //! The [`pin-init`] crate is the way such structs are initialized on the Rust side. Please refer
9 //! to its documentation to better understand how to use it. Additionally, there are many examples
10 //! throughout the kernel, such as the types from the [`sync`] module. And the ones presented
11 //! below.
12 //!
13 //! [`sync`]: crate::sync
14 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html
15 //! [`pin-init`]: https://rust.docs.kernel.org/pin_init/
16 //!
17 //! # [`Opaque<T>`]
18 //!
19 //! For the special case where initializing a field is a single FFI-function call that cannot fail,
20 //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single
21 //! [`Opaque<T>`] field by just delegating to the supplied closure. You can use these in
22 //! combination with [`pin_init!`].
23 //!
24 //! [`Opaque<T>`]: crate::types::Opaque
25 //! [`Opaque::ffi_init`]: crate::types::Opaque::ffi_init
26 //! [`pin_init!`]: pin_init::pin_init
27 //!
28 //! # Examples
29 //!
30 //! ## General Examples
31 //!
32 //! ```rust
33 //! # #![expect(clippy::undocumented_unsafe_blocks)]
34 //! use kernel::types::Opaque;
35 //! use pin_init::pin_init_from_closure;
36 //!
37 //! // assume we have some `raw_foo` type in C:
38 //! #[repr(C)]
39 //! struct RawFoo([u8; 16]);
40 //! extern "C" {
41 //!     fn init_foo(_: *mut RawFoo);
42 //! }
43 //!
44 //! #[pin_data]
45 //! struct Foo {
46 //!     #[pin]
47 //!     raw: Opaque<RawFoo>,
48 //! }
49 //!
50 //! impl Foo {
51 //!     fn setup(self: Pin<&mut Self>) {
52 //!         pr_info!("Setting up foo\n");
53 //!     }
54 //! }
55 //!
56 //! let foo = pin_init!(Foo {
57 //!     raw <- unsafe {
58 //!         Opaque::ffi_init(|s| {
59 //!             // note that this cannot fail.
60 //!             init_foo(s);
61 //!         })
62 //!     },
63 //! }).pin_chain(|foo| {
64 //!     foo.setup();
65 //!     Ok(())
66 //! });
67 //! ```
68 //!
69 //! ```rust
70 //! use kernel::{prelude::*, types::Opaque};
71 //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};
72 //! # mod bindings {
73 //! #     #![expect(non_camel_case_types, clippy::missing_safety_doc)]
74 //! #     pub struct foo;
75 //! #     pub unsafe fn init_foo(_ptr: *mut foo) {}
76 //! #     pub unsafe fn destroy_foo(_ptr: *mut foo) {}
77 //! #     pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }
78 //! # }
79 //! /// # Invariants
80 //! ///
81 //! /// `foo` is always initialized
82 //! #[pin_data(PinnedDrop)]
83 //! pub struct RawFoo {
84 //!     #[pin]
85 //!     foo: Opaque<bindings::foo>,
86 //!     #[pin]
87 //!     _p: PhantomPinned,
88 //! }
89 //!
90 //! impl RawFoo {
91 //!     pub fn new(flags: u32) -> impl PinInit<Self, Error> {
92 //!         // SAFETY:
93 //!         // - when the closure returns `Ok(())`, then it has successfully initialized and
94 //!         //   enabled `foo`,
95 //!         // - when it returns `Err(e)`, then it has cleaned up before
96 //!         unsafe {
97 //!             pin_init::pin_init_from_closure(move |slot: *mut Self| {
98 //!                 // `slot` contains uninit memory, avoid creating a reference.
99 //!                 let foo = addr_of_mut!((*slot).foo);
100 //!
101 //!                 // Initialize the `foo`
102 //!                 bindings::init_foo(Opaque::cast_into(foo));
103 //!
104 //!                 // Try to enable it.
105 //!                 let err = bindings::enable_foo(Opaque::cast_into(foo), flags);
106 //!                 if err != 0 {
107 //!                     // Enabling has failed, first clean up the foo and then return the error.
108 //!                     bindings::destroy_foo(Opaque::cast_into(foo));
109 //!                     return Err(Error::from_errno(err));
110 //!                 }
111 //!
112 //!                 // All fields of `RawFoo` have been initialized, since `_p` is a ZST.
113 //!                 Ok(())
114 //!             })
115 //!         }
116 //!     }
117 //! }
118 //!
119 //! #[pinned_drop]
120 //! impl PinnedDrop for RawFoo {
121 //!     fn drop(self: Pin<&mut Self>) {
122 //!         // SAFETY: Since `foo` is initialized, destroying is safe.
123 //!         unsafe { bindings::destroy_foo(self.foo.get()) };
124 //!     }
125 //! }
126 //! ```
127 
128 use crate::{
129     alloc::{AllocError, Flags},
130     error::{self, Error},
131 };
132 use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit};
133 
134 /// Smart pointer that can initialize memory in-place.
135 pub trait InPlaceInit<T>: Sized {
136     /// Pinned version of `Self`.
137     ///
138     /// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use
139     /// `Self`, otherwise just use `Pin<Self>`.
140     type PinnedSelf;
141 
142     /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
143     /// type.
144     ///
145     /// If `T: !Unpin` it will not be able to move afterwards.
try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> where E: From<AllocError>146     fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
147     where
148         E: From<AllocError>;
149 
150     /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
151     /// type.
152     ///
153     /// If `T: !Unpin` it will not be able to move afterwards.
pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf> where Error: From<E>,154     fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf>
155     where
156         Error: From<E>,
157     {
158         // SAFETY: We delegate to `init` and only change the error type.
159         let init = unsafe {
160             pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
161         };
162         Self::try_pin_init(init, flags)
163     }
164 
165     /// Use the given initializer to in-place initialize a `T`.
try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> where E: From<AllocError>166     fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
167     where
168         E: From<AllocError>;
169 
170     /// Use the given initializer to in-place initialize a `T`.
init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self> where Error: From<E>,171     fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
172     where
173         Error: From<E>,
174     {
175         // SAFETY: We delegate to `init` and only change the error type.
176         let init = unsafe {
177             init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
178         };
179         Self::try_init(init, flags)
180     }
181 }
182 
183 /// Construct an in-place fallible initializer for `struct`s.
184 ///
185 /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use
186 /// [`init!`].
187 ///
188 /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error,
189 /// append `? $type` after the `struct` initializer.
190 /// The safety caveats from [`try_pin_init!`] also apply:
191 /// - `unsafe` code must guarantee either full initialization or return an error and allow
192 ///   deallocation of the memory.
193 /// - the fields are initialized in the order given in the initializer.
194 /// - no references to fields are allowed to be created inside of the initializer.
195 ///
196 /// # Examples
197 ///
198 /// ```rust
199 /// use kernel::error::Error;
200 /// use pin_init::init_zeroed;
201 /// struct BigBuf {
202 ///     big: KBox<[u8; 1024 * 1024 * 1024]>,
203 ///     small: [u8; 1024 * 1024],
204 /// }
205 ///
206 /// impl BigBuf {
207 ///     fn new() -> impl Init<Self, Error> {
208 ///         try_init!(Self {
209 ///             big: KBox::init(init_zeroed(), GFP_KERNEL)?,
210 ///             small: [0; 1024 * 1024],
211 ///         }? Error)
212 ///     }
213 /// }
214 /// ```
215 ///
216 /// [`Infallible`]: core::convert::Infallible
217 /// [`init!`]: pin_init::init
218 /// [`try_pin_init!`]: crate::try_pin_init!
219 /// [`Error`]: crate::error::Error
220 #[macro_export]
221 macro_rules! try_init {
222     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
223         $($fields:tt)*
224     }) => {
225         ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? {
226             $($fields)*
227         }? $crate::error::Error)
228     };
229     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
230         $($fields:tt)*
231     }? $err:ty) => {
232         ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),*>)? {
233             $($fields)*
234         }? $err)
235     };
236 }
237 
238 /// Construct an in-place, fallible pinned initializer for `struct`s.
239 ///
240 /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].
241 ///
242 /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop
243 /// initialization and return the error.
244 ///
245 /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when
246 /// initialization fails, the memory can be safely deallocated without any further modifications.
247 ///
248 /// This macro defaults the error to [`Error`].
249 ///
250 /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`
251 /// after the `struct` initializer to specify the error type you want to use.
252 ///
253 /// # Examples
254 ///
255 /// ```rust
256 /// # #![feature(new_uninit)]
257 /// use kernel::error::Error;
258 /// use pin_init::init_zeroed;
259 /// #[pin_data]
260 /// struct BigBuf {
261 ///     big: KBox<[u8; 1024 * 1024 * 1024]>,
262 ///     small: [u8; 1024 * 1024],
263 ///     ptr: *mut u8,
264 /// }
265 ///
266 /// impl BigBuf {
267 ///     fn new() -> impl PinInit<Self, Error> {
268 ///         try_pin_init!(Self {
269 ///             big: KBox::init(init_zeroed(), GFP_KERNEL)?,
270 ///             small: [0; 1024 * 1024],
271 ///             ptr: core::ptr::null_mut(),
272 ///         }? Error)
273 ///     }
274 /// }
275 /// ```
276 ///
277 /// [`Infallible`]: core::convert::Infallible
278 /// [`pin_init!`]: pin_init::pin_init
279 /// [`Error`]: crate::error::Error
280 #[macro_export]
281 macro_rules! try_pin_init {
282     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
283         $($fields:tt)*
284     }) => {
285         ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {
286             $($fields)*
287         }? $crate::error::Error)
288     };
289     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
290         $($fields:tt)*
291     }? $err:ty) => {
292         ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {
293             $($fields)*
294         }? $err)
295     };
296 }
297