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
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
128use crate::{
129 alloc::{AllocError, Flags},
130 error::{self, Error},
131};
132use pin_init::{init_from_closure, pin_init_from_closure, Init, PinInit};
133
134/// Smart pointer that can initialize memory in-place.
135pub 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.
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.
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`.
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`.
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]
221macro_rules! try_init {
222 ($($args:tt)*) => {
223 ::pin_init::init!(
224 #[default_error($crate::error::Error)]
225 $($args)*
226 )
227 }
228}
229
230/// Construct an in-place, fallible pinned initializer for `struct`s.
231///
232/// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].
233///
234/// You can use the `?` operator or use `return Err(err)` inside the initializer to stop
235/// initialization and return the error.
236///
237/// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when
238/// initialization fails, the memory can be safely deallocated without any further modifications.
239///
240/// This macro defaults the error to [`Error`].
241///
242/// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`
243/// after the `struct` initializer to specify the error type you want to use.
244///
245/// # Examples
246///
247/// ```rust
248/// # #![feature(new_uninit)]
249/// use kernel::error::Error;
250/// use pin_init::init_zeroed;
251/// #[pin_data]
252/// struct BigBuf {
253/// big: KBox<[u8; 1024 * 1024 * 1024]>,
254/// small: [u8; 1024 * 1024],
255/// ptr: *mut u8,
256/// }
257///
258/// impl BigBuf {
259/// fn new() -> impl PinInit<Self, Error> {
260/// try_pin_init!(Self {
261/// big: KBox::init(init_zeroed(), GFP_KERNEL)?,
262/// small: [0; 1024 * 1024],
263/// ptr: core::ptr::null_mut(),
264/// }? Error)
265/// }
266/// }
267/// ```
268///
269/// [`Infallible`]: core::convert::Infallible
270/// [`pin_init!`]: pin_init::pin_init
271/// [`Error`]: crate::error::Error
272#[macro_export]
273macro_rules! try_pin_init {
274 ($($args:tt)*) => {
275 ::pin_init::pin_init!(
276 #[default_error($crate::error::Error)]
277 $($args)*
278 )
279 }
280}