at v6.15-rc4 305 lines 10 kB view raw
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}