FILE
init.rs
File preview with syntax highlighting.
linux-6.19.14/rust/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 ($(&$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] 281macro_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}
~/
Read-only file preview.