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