kernel/init.rs
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,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\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,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
137use crate::{
138 alloc::{AllocError, Flags},
139 error::{self, Error},
140};
141use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit};
142
143/// Smart pointer that can initialize memory in-place.
144pub trait InPlaceInit<T>: Sized {
145 /// Pinned version of `Self`.
146 ///
147 /// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use
148 /// `Self`, otherwise just use `Pin<Self>`.
149 type PinnedSelf;
150
151 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
152 /// type.
153 ///
154 /// If `T: !Unpin` it will not be able to move afterwards.
155 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
156 where
157 E: From<AllocError>;
158
159 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
160 /// type.
161 ///
162 /// If `T: !Unpin` it will not be able to move afterwards.
163 fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf>
164 where
165 Error: From<E>,
166 {
167 // SAFETY: We delegate to `init` and only change the error type.
168 let init = unsafe {
169 pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
170 };
171 Self::try_pin_init(init, flags)
172 }
173
174 /// Use the given initializer to in-place initialize a `T`.
175 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
176 where
177 E: From<AllocError>;
178
179 /// Use the given initializer to in-place initialize a `T`.
180 fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
181 where
182 Error: From<E>,
183 {
184 // SAFETY: We delegate to `init` and only change the error type.
185 let init = unsafe {
186 init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
187 };
188 Self::try_init(init, flags)
189 }
190}
191
192/// Construct an in-place fallible initializer for `struct`s.
193///
194/// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use
195/// [`init!`].
196///
197/// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error,
198/// append `? $type` after the `struct` initializer.
199/// The safety caveats from [`try_pin_init!`] also apply:
200/// - `unsafe` code must guarantee either full initialization or return an error and allow
201/// deallocation of the memory.
202/// - the fields are initialized in the order given in the initializer.
203/// - no references to fields are allowed to be created inside of the initializer.
204///
205/// # Examples
206///
207/// ```rust
208/// use kernel::error::Error;
209/// use pin_init::zeroed;
210/// struct BigBuf {
211/// big: KBox<[u8; 1024 * 1024 * 1024]>,
212/// small: [u8; 1024 * 1024],
213/// }
214///
215/// impl BigBuf {
216/// fn new() -> impl Init<Self, Error> {
217/// try_init!(Self {
218/// big: KBox::init(zeroed(), GFP_KERNEL)?,
219/// small: [0; 1024 * 1024],
220/// }? Error)
221/// }
222/// }
223/// ```
224///
225/// [`Infallible`]: core::convert::Infallible
226/// [`init!`]: pin_init::init
227/// [`try_pin_init!`]: crate::try_pin_init!
228/// [`Error`]: crate::error::Error
229#[macro_export]
230macro_rules! try_init {
231 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
232 $($fields:tt)*
233 }) => {
234 ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
235 $($fields)*
236 }? $crate::error::Error)
237 };
238 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
239 $($fields:tt)*
240 }? $err:ty) => {
241 ::pin_init::try_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
242 $($fields)*
243 }? $err)
244 };
245}
246
247/// Construct an in-place, fallible pinned initializer for `struct`s.
248///
249/// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].
250///
251/// You can use the `?` operator or use `return Err(err)` inside the initializer to stop
252/// initialization and return the error.
253///
254/// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when
255/// initialization fails, the memory can be safely deallocated without any further modifications.
256///
257/// This macro defaults the error to [`Error`].
258///
259/// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`
260/// after the `struct` initializer to specify the error type you want to use.
261///
262/// # Examples
263///
264/// ```rust
265/// # #![feature(new_uninit)]
266/// use kernel::error::Error;
267/// use pin_init::zeroed;
268/// #[pin_data]
269/// struct BigBuf {
270/// big: KBox<[u8; 1024 * 1024 * 1024]>,
271/// small: [u8; 1024 * 1024],
272/// ptr: *mut u8,
273/// }
274///
275/// impl BigBuf {
276/// fn new() -> impl PinInit<Self, Error> {
277/// try_pin_init!(Self {
278/// big: KBox::init(zeroed(), GFP_KERNEL)?,
279/// small: [0; 1024 * 1024],
280/// ptr: core::ptr::null_mut(),
281/// }? Error)
282/// }
283/// }
284/// ```
285///
286/// [`Infallible`]: core::convert::Infallible
287/// [`pin_init!`]: pin_init::pin_init
288/// [`Error`]: crate::error::Error
289#[macro_export]
290macro_rules! try_pin_init {
291 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
292 $($fields:tt)*
293 }) => {
294 ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
295 $($fields)*
296 }? $crate::error::Error)
297 };
298 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
299 $($fields:tt)*
300 }? $err:ty) => {
301 ::pin_init::try_pin_init!($(&$this in)? $t $(::<$($generics),* $(,)?>)? {
302 $($fields)*
303 }? $err)
304 };
305}