Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: pin-init: synchronize documentation with the user-space version

Synchronize documentation and examples with the user-space version.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250308110339.2997091-18-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

authored by

Benno Lossin and committed by
Miguel Ojeda
02c01c08 9b2299af

+115 -54
+3 -5
rust/pin-init/src/__internal.rs
··· 1 1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 2 3 - //! This module contains API-internal items for pin-init. 3 + //! This module contains library internal items. 4 4 //! 5 - //! These items must not be used outside of 6 - //! - `kernel/init.rs` 7 - //! - `macros/pin_data.rs` 8 - //! - `macros/pinned_drop.rs` 5 + //! These items must not be used outside of this crate and the pin-init-internal crate located at 6 + //! `../internal`. 9 7 10 8 use super::*; 11 9
+102 -39
rust/pin-init/src/lib.rs
··· 1 1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 2 3 - //! API to safely and fallibly initialize pinned `struct`s using in-place constructors. 3 + //! Library to safely and fallibly initialize pinned `struct`s using in-place constructors. 4 + //! 5 + //! [Pinning][pinning] is Rust's way of ensuring data does not move. 4 6 //! 5 7 //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack 6 8 //! overflow. 9 + //! 10 + //! This library's main use-case is in [Rust-for-Linux]. Although this version can be used 11 + //! standalone. 12 + //! 13 + //! There are cases when you want to in-place initialize a struct. For example when it is very big 14 + //! and moving it from the stack is not an option, because it is bigger than the stack itself. 15 + //! Another reason would be that you need the address of the object to initialize it. This stands 16 + //! in direct conflict with Rust's normal process of first initializing an object and then moving 17 + //! it into it's final memory location. For more information, see 18 + //! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>. 19 + //! 20 + //! This library allows you to do in-place initialization safely. 21 + //! 22 + //! ## Nightly Needed for `alloc` feature 23 + //! 24 + //! This library requires the [`allocator_api` unstable feature] when the `alloc` feature is 25 + //! enabled and thus this feature can only be used with a nightly compiler. When enabling the 26 + //! `alloc` feature, the user will be required to activate `allocator_api` as well. 27 + //! 28 + //! [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html 29 + //! 30 + //! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler. 31 + //! However, using the crate on stable compilers is possible by disabling `alloc`. In practice this 32 + //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std 33 + //! mode. 7 34 //! 8 35 //! # Overview 9 36 //! ··· 44 17 //! - a custom function/macro returning an in-place constructor provided by someone else, 45 18 //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer. 46 19 //! 47 - //! Aside from pinned initialization, this API also supports in-place construction without pinning, 48 - //! the macros/types/functions are generally named like the pinned variants without the `pin` 49 - //! prefix. 20 + //! Aside from pinned initialization, this library also supports in-place construction without 21 + //! pinning, the macros/types/functions are generally named like the pinned variants without the 22 + //! `pin_` prefix. 50 23 //! 51 24 //! # Examples 25 + //! 26 + //! Throughout the examples we will often make use of the `CMutex` type which can be found in 27 + //! `../examples/mutex.rs`. It is essentially a userland rebuild of the `struct mutex` type from 28 + //! the Linux kernel. It also uses a wait list and a basic spinlock. Importantly the wait list 29 + //! requires it to be pinned to be locked and thus is a prime candidate for using this library. 52 30 //! 53 31 //! ## Using the [`pin_init!`] macro 54 32 //! ··· 68 36 //! # #![feature(allocator_api)] 69 37 //! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; 70 38 //! # use core::pin::Pin; 71 - //! use pin_init::*; 39 + //! use pin_init::{pin_data, pin_init, InPlaceInit}; 72 40 //! 73 41 //! #[pin_data] 74 42 //! struct Foo { ··· 112 80 //! 113 81 //! ## Using a custom function/macro that returns an initializer 114 82 //! 115 - //! Many types from the kernel supply a function/macro that returns an initializer, because the 116 - //! above method only works for types where you can access the fields. 83 + //! Many types that use this library supply a function/macro that returns an initializer, because 84 + //! the above method only works for types where you can access the fields. 117 85 //! 118 86 //! ```rust,ignore 119 87 //! # #![feature(allocator_api)] ··· 164 132 //! 165 133 //! ```rust,ignore 166 134 //! # #![feature(extern_types)] 167 - //! use pin_init::*; 135 + //! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure}; 168 136 //! use core::{ 169 137 //! ptr::addr_of_mut, 170 138 //! marker::PhantomPinned, ··· 173 141 //! mem::MaybeUninit, 174 142 //! }; 175 143 //! mod bindings { 144 + //! #[repr(C)] 145 + //! pub struct foo { 146 + //! /* fields from C ... */ 147 + //! } 176 148 //! extern "C" { 177 - //! pub type foo; 178 149 //! pub fn init_foo(ptr: *mut foo); 179 150 //! pub fn destroy_foo(ptr: *mut foo); 180 151 //! #[must_use = "you must check the error return code"] ··· 235 200 //! } 236 201 //! ``` 237 202 //! 203 + //! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside 204 + //! the `kernel` crate. The [`sync`] module is a good starting point. 205 + //! 206 + //! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html 238 207 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 239 208 //! [structurally pinned fields]: 240 209 //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field ··· 253 214 )] 254 215 #![cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")] 255 216 #![cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")] 256 - //! [`impl PinInit<Foo>`]: PinInit 257 - //! [`impl PinInit<T, E>`]: PinInit 258 - //! [`impl Init<T, E>`]: Init 259 - //! [`pin_data`]: crate::pin_data 260 - //! [`pin_init!`]: crate::pin_init! 217 + //! [`impl PinInit<Foo>`]: crate::PinInit 218 + //! [`impl PinInit<T, E>`]: crate::PinInit 219 + //! [`impl Init<T, E>`]: crate::Init 220 + //! [Rust-for-Linux]: https://rust-for-linux.com/ 261 221 262 222 #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] 263 223 #![cfg_attr( ··· 442 404 /// A normal `let` binding with optional type annotation. The expression is expected to implement 443 405 /// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error 444 406 /// type, then use [`stack_try_pin_init!`]. 445 - /// 446 - /// [`stack_try_pin_init!`]: crate::stack_try_pin_init! 447 407 #[macro_export] 448 408 macro_rules! stack_pin_init { 449 409 (let $var:ident $(: $t:ty)? = $val:expr) => { ··· 578 542 /// 579 543 /// # Init-functions 580 544 /// 581 - /// When working with this API it is often desired to let others construct your types without 582 - /// giving access to all fields. This is where you would normally write a plain function `new` 583 - /// that would return a new instance of your type. With this API that is also possible. 584 - /// However, there are a few extra things to keep in mind. 545 + /// When working with this library it is often desired to let others construct your types without 546 + /// giving access to all fields. This is where you would normally write a plain function `new` that 547 + /// would return a new instance of your type. With this library that is also possible. However, 548 + /// there are a few extra things to keep in mind. 585 549 /// 586 550 /// To create an initializer function, simply declare it like this: 587 551 /// ··· 710 674 /// #[pin] 711 675 /// pin: PhantomPinned, 712 676 /// } 713 - /// pin_init!(&this in Buf { 677 + /// 678 + /// let init = pin_init!(&this in Buf { 714 679 /// buf: [0; 64], 715 680 /// // SAFETY: TODO. 716 681 /// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() }, 717 682 /// pin: PhantomPinned, 718 683 /// }); 719 - /// pin_init!(Buf { 684 + /// let init = pin_init!(Buf { 720 685 /// buf: [1; 64], 721 686 /// ..Zeroable::zeroed() 722 687 /// }); 723 688 /// ``` 724 689 /// 725 - /// [`try_pin_init!`]: crate::try_pin_init 726 690 /// [`NonNull<Self>`]: core::ptr::NonNull 727 691 // For a detailed example of how this macro works, see the module documentation of the hidden 728 - // module `__internal` inside of `init/__internal.rs`. 692 + // module `macros` inside of `macros.rs`. 729 693 #[macro_export] 730 694 macro_rules! pin_init { 731 695 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { ··· 755 719 /// ```rust,ignore 756 720 /// # #![feature(allocator_api)] 757 721 /// # #[path = "../examples/error.rs"] mod error; use error::Error; 758 - /// use pin_init::*; 722 + /// use pin_init::{pin_data, try_pin_init, PinInit, InPlaceInit, zeroed}; 723 + /// 759 724 /// #[pin_data] 760 725 /// struct BigBuf { 761 726 /// big: Box<[u8; 1024 * 1024 * 1024]>, ··· 767 730 /// impl BigBuf { 768 731 /// fn new() -> impl PinInit<Self, Error> { 769 732 /// try_pin_init!(Self { 770 - /// big: Box::init(init::zeroed())?, 733 + /// big: Box::init(zeroed())?, 771 734 /// small: [0; 1024 * 1024], 772 735 /// ptr: core::ptr::null_mut(), 773 736 /// }? Error) ··· 776 739 /// # let _ = Box::pin_init(BigBuf::new()); 777 740 /// ``` 778 741 // For a detailed example of how this macro works, see the module documentation of the hidden 779 - // module `__internal` inside of `init/__internal.rs`. 742 + // module `macros` inside of `macros.rs`. 780 743 #[macro_export] 781 744 macro_rules! try_pin_init { 782 745 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { ··· 809 772 /// This initializer is for initializing data in-place that might later be moved. If you want to 810 773 /// pin-initialize, use [`pin_init!`]. 811 774 /// 812 - /// [`try_init!`]: crate::try_init! 775 + /// # Examples 776 + /// 777 + /// ```rust 778 + /// # #![feature(allocator_api)] 779 + /// # #[path = "../examples/error.rs"] mod error; use error::Error; 780 + /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; 781 + /// # use pin_init::InPlaceInit; 782 + /// use pin_init::{init, Init, zeroed}; 783 + /// 784 + /// struct BigBuf { 785 + /// small: [u8; 1024 * 1024], 786 + /// } 787 + /// 788 + /// impl BigBuf { 789 + /// fn new() -> impl Init<Self> { 790 + /// init!(Self { 791 + /// small <- zeroed(), 792 + /// }) 793 + /// } 794 + /// } 795 + /// # let _ = Box::init(BigBuf::new()); 796 + /// ``` 813 797 // For a detailed example of how this macro works, see the module documentation of the hidden 814 - // module `__internal` inside of `init/__internal.rs`. 798 + // module `macros` inside of `macros.rs`. 815 799 #[macro_export] 816 800 macro_rules! init { 817 801 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { ··· 862 804 /// ```rust,ignore 863 805 /// # #![feature(allocator_api)] 864 806 /// # use core::alloc::AllocError; 865 - /// use pin_init::*; 807 + /// # use pin_init::InPlaceInit; 808 + /// use pin_init::{try_init, Init, zeroed}; 809 + /// 866 810 /// struct BigBuf { 867 811 /// big: Box<[u8; 1024 * 1024 * 1024]>, 868 812 /// small: [u8; 1024 * 1024], ··· 878 818 /// }? AllocError) 879 819 /// } 880 820 /// } 821 + /// # let _ = Box::init(BigBuf::new()); 881 822 /// ``` 882 - /// [`try_pin_init!`]: crate::try_pin_init 883 823 // For a detailed example of how this macro works, see the module documentation of the hidden 884 - // module `__internal` inside of `init/__internal.rs`. 824 + // module `macros` inside of `macros.rs`. 885 825 #[macro_export] 886 826 macro_rules! try_init { 887 827 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { ··· 907 847 /// 908 848 /// This will succeed: 909 849 /// ```ignore 910 - /// use pin_init::assert_pinned; 850 + /// use pin_init::{pin_data, assert_pinned}; 851 + /// 911 852 /// #[pin_data] 912 853 /// struct MyStruct { 913 854 /// #[pin] ··· 920 859 /// 921 860 /// This will fail: 922 861 /// ```compile_fail,ignore 923 - /// use pin_init::assert_pinned; 862 + /// use pin_init::{pin_data, assert_pinned}; 863 + /// 924 864 /// #[pin_data] 925 865 /// struct MyStruct { 926 866 /// some_field: u64, ··· 934 872 /// work around this, you may pass the `inline` parameter to the macro. The `inline` parameter can 935 873 /// only be used when the macro is invoked from a function body. 936 874 /// ```ignore 937 - /// use pin_init::assert_pinned; 875 + /// # use core::pin::Pin; 876 + /// use pin_init::{pin_data, assert_pinned}; 877 + /// 938 878 /// #[pin_data] 939 879 /// struct Foo<T> { 940 880 /// #[pin] ··· 1120 1056 /// 1121 1057 /// ```rust,ignore 1122 1058 /// # #![expect(clippy::disallowed_names)] 1123 - /// use pin_init::{init_from_closure, zeroed}; 1059 + /// use pin_init::{init, zeroed, Init}; 1060 + /// 1124 1061 /// struct Foo { 1125 1062 /// buf: [u8; 1_000_000], 1126 1063 /// } 1127 1064 /// 1128 1065 /// impl Foo { 1129 1066 /// fn setup(&mut self) { 1130 - /// pr_info!("Setting up foo"); 1067 + /// println!("Setting up foo"); 1131 1068 /// } 1132 1069 /// } 1133 1070 /// ··· 1367 1302 /// # Safety 1368 1303 /// 1369 1304 /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl. 1370 - /// 1371 - /// [`pinned_drop`]: crate::pinned_drop 1372 1305 pub unsafe trait PinnedDrop: __internal::HasPinData { 1373 1306 /// Executes the pinned destructor of this type. 1374 1307 ///
+10 -10
rust/pin-init/src/macros.rs
··· 1 1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 2 3 3 //! This module provides the macros that actually implement the proc-macros `pin_data` and 4 - //! `pinned_drop`. It also contains `__init_internal` the implementation of the `{try_}{pin_}init!` 5 - //! macros. 4 + //! `pinned_drop`. It also contains `__init_internal`, the implementation of the 5 + //! `{try_}{pin_}init!` macros. 6 6 //! 7 7 //! These macros should never be called directly, since they expect their input to be 8 8 //! in a certain format which is internal. If used incorrectly, these macros can lead to UB even in ··· 11 11 //! This architecture has been chosen because the kernel does not yet have access to `syn` which 12 12 //! would make matters a lot easier for implementing these as proc-macros. 13 13 //! 14 + //! Since this library and the kernel implementation should diverge as little as possible, the same 15 + //! approach has been taken here. 16 + //! 14 17 //! # Macro expansion example 15 18 //! 16 19 //! This section is intended for readers trying to understand the macros in this module and the 17 - //! `pin_init!` macros from `init.rs`. 20 + //! `[try_][pin_]init!` macros from `lib.rs`. 18 21 //! 19 22 //! We will look at the following example: 20 23 //! 21 24 //! ```rust,ignore 22 - //! # use pin_init::*; 23 - //! # use core::pin::Pin; 24 25 //! #[pin_data] 25 26 //! #[repr(C)] 26 27 //! struct Bar<T> { ··· 46 45 //! #[pinned_drop] 47 46 //! impl PinnedDrop for Foo { 48 47 //! fn drop(self: Pin<&mut Self>) { 49 - //! pr_info!("{self:p} is getting dropped."); 48 + //! println!("{self:p} is getting dropped."); 50 49 //! } 51 50 //! } 52 51 //! ··· 76 75 //! Here is the definition of `Bar` from our example: 77 76 //! 78 77 //! ```rust,ignore 79 - //! # use pin_init::*; 80 78 //! #[pin_data] 81 79 //! #[repr(C)] 82 80 //! struct Bar<T> { ··· 251 251 //! // is an error later. This `DropGuard` will drop the field when it gets 252 252 //! // dropped and has not yet been forgotten. 253 253 //! let __t_guard = unsafe { 254 - //! ::pinned_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).t)) 254 + //! ::pin_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).t)) 255 255 //! }; 256 256 //! // Expansion of `x: 0,`: 257 257 //! // Since this can be an arbitrary expression we cannot place it inside ··· 412 412 //! #[pinned_drop] 413 413 //! impl PinnedDrop for Foo { 414 414 //! fn drop(self: Pin<&mut Self>) { 415 - //! pr_info!("{self:p} is getting dropped."); 415 + //! println!("{self:p} is getting dropped."); 416 416 //! } 417 417 //! } 418 418 //! ``` ··· 423 423 //! // `unsafe`, full path and the token parameter are added, everything else stays the same. 424 424 //! unsafe impl ::pin_init::PinnedDrop for Foo { 425 425 //! fn drop(self: Pin<&mut Self>, _: ::pin_init::__internal::OnlyCallFromDrop) { 426 - //! pr_info!("{self:p} is getting dropped."); 426 + //! println!("{self:p} is getting dropped."); 427 427 //! } 428 428 //! } 429 429 //! ```