xref: /linux-6.15/rust/kernel/init.rs (revision 578eb8b6)
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!`]: crate::pin_init
27 //!
28 //! # Examples
29 //!
30 //! ## General Examples
31 //!
32 //! ```rust,ignore
33 //! # #![allow(clippy::disallowed_names)]
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 {
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");
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,ignore
70 //! # #![allow(unreachable_pub, clippy::disallowed_names)]
71 //! use kernel::{prelude::*, types::Opaque};
72 //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};
73 //! # mod bindings {
74 //! #     #![allow(non_camel_case_types)]
75 //! #     pub struct foo;
76 //! #     pub unsafe fn init_foo(_ptr: *mut foo) {}
77 //! #     pub unsafe fn destroy_foo(_ptr: *mut foo) {}
78 //! #     pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }
79 //! # }
80 //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.
81 //! # trait FromErrno {
82 //! #     fn from_errno(errno: core::ffi::c_int) -> Error {
83 //! #         // Dummy error that can be constructed outside the `kernel` crate.
84 //! #         Error::from(core::fmt::Error)
85 //! #     }
86 //! # }
87 //! # impl FromErrno for Error {}
88 //! /// # Invariants
89 //! ///
90 //! /// `foo` is always initialized
91 //! #[pin_data(PinnedDrop)]
92 //! pub struct RawFoo {
93 //!     #[pin]
94 //!     foo: Opaque<bindings::foo>,
95 //!     #[pin]
96 //!     _p: PhantomPinned,
97 //! }
98 //!
99 //! impl RawFoo {
100 //!     pub fn new(flags: u32) -> impl PinInit<Self, Error> {
101 //!         // SAFETY:
102 //!         // - when the closure returns `Ok(())`, then it has successfully initialized and
103 //!         //   enabled `foo`,
104 //!         // - when it returns `Err(e)`, then it has cleaned up before
105 //!         unsafe {
106 //!             pin_init::pin_init_from_closure(move |slot: *mut Self| {
107 //!                 // `slot` contains uninit memory, avoid creating a reference.
108 //!                 let foo = addr_of_mut!((*slot).foo);
109 //!
110 //!                 // Initialize the `foo`
111 //!                 bindings::init_foo(Opaque::raw_get(foo));
112 //!
113 //!                 // Try to enable it.
114 //!                 let err = bindings::enable_foo(Opaque::raw_get(foo), flags);
115 //!                 if err != 0 {
116 //!                     // Enabling has failed, first clean up the foo and then return the error.
117 //!                     bindings::destroy_foo(Opaque::raw_get(foo));
118 //!                     return Err(Error::from_errno(err));
119 //!                 }
120 //!
121 //!                 // All fields of `RawFoo` have been initialized, since `_p` is a ZST.
122 //!                 Ok(())
123 //!             })
124 //!         }
125 //!     }
126 //! }
127 //!
128 //! #[pinned_drop]
129 //! impl PinnedDrop for RawFoo {
130 //!     fn drop(self: Pin<&mut Self>) {
131 //!         // SAFETY: Since `foo` is initialized, destroying is safe.
132 //!         unsafe { bindings::destroy_foo(self.foo.get()) };
133 //!     }
134 //! }
135 //! ```
136 
137 /// Construct an in-place fallible initializer for `struct`s.
138 ///
139 /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use
140 /// [`init!`].
141 ///
142 /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error,
143 /// append `? $type` after the `struct` initializer.
144 /// The safety caveats from [`try_pin_init!`] also apply:
145 /// - `unsafe` code must guarantee either full initialization or return an error and allow
146 ///   deallocation of the memory.
147 /// - the fields are initialized in the order given in the initializer.
148 /// - no references to fields are allowed to be created inside of the initializer.
149 ///
150 /// # Examples
151 ///
152 /// ```rust
153 /// use kernel::{init::zeroed, error::Error};
154 /// struct BigBuf {
155 ///     big: KBox<[u8; 1024 * 1024 * 1024]>,
156 ///     small: [u8; 1024 * 1024],
157 /// }
158 ///
159 /// impl BigBuf {
160 ///     fn new() -> impl Init<Self, Error> {
161 ///         try_init!(Self {
162 ///             big: KBox::init(zeroed(), GFP_KERNEL)?,
163 ///             small: [0; 1024 * 1024],
164 ///         }? Error)
165 ///     }
166 /// }
167 /// ```
168 ///
169 /// [`Infallible`]: core::convert::Infallible
170 /// [`init!`]: crate::init!
171 /// [`try_pin_init!`]: crate::try_pin_init!
172 /// [`Error`]: crate::error::Error
173 #[macro_export]
174 macro_rules! try_init {
175     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
176         $($fields:tt)*
177     }) => {
178         $crate::_try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
179             $($fields)*
180         }? $crate::error::Error)
181     };
182     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
183         $($fields:tt)*
184     }? $err:ty) => {
185         $crate::_try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
186             $($fields)*
187         }? $err)
188     };
189 }
190 
191 /// Construct an in-place, fallible pinned initializer for `struct`s.
192 ///
193 /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].
194 ///
195 /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop
196 /// initialization and return the error.
197 ///
198 /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when
199 /// initialization fails, the memory can be safely deallocated without any further modifications.
200 ///
201 /// This macro defaults the error to [`Error`].
202 ///
203 /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`
204 /// after the `struct` initializer to specify the error type you want to use.
205 ///
206 /// # Examples
207 ///
208 /// ```rust
209 /// # #![feature(new_uninit)]
210 /// use kernel::{init::zeroed, error::Error};
211 /// #[pin_data]
212 /// struct BigBuf {
213 ///     big: KBox<[u8; 1024 * 1024 * 1024]>,
214 ///     small: [u8; 1024 * 1024],
215 ///     ptr: *mut u8,
216 /// }
217 ///
218 /// impl BigBuf {
219 ///     fn new() -> impl PinInit<Self, Error> {
220 ///         try_pin_init!(Self {
221 ///             big: KBox::init(zeroed(), GFP_KERNEL)?,
222 ///             small: [0; 1024 * 1024],
223 ///             ptr: core::ptr::null_mut(),
224 ///         }? Error)
225 ///     }
226 /// }
227 /// ```
228 ///
229 /// [`Infallible`]: core::convert::Infallible
230 /// [`pin_init!`]: crate::pin_init
231 /// [`Error`]: crate::error::Error
232 #[macro_export]
233 macro_rules! try_pin_init {
234     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
235         $($fields:tt)*
236     }) => {
237         $crate::_try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
238             $($fields)*
239         }? $crate::error::Error)
240     };
241     ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
242         $($fields:tt)*
243     }? $err:ty) => {
244         $crate::_try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
245             $($fields)*
246         }? $err)
247     };
248 }
249