From 41b6a8122d888299e3e437dae3a36431e6dfd5c9 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sun, 5 Jan 2025 19:40:06 +0000 Subject: rust: alloc: make `ReallocFunc::call` inline This function can be called with different function pointers when different allocator (e.g. Kmalloc, Vmalloc, KVmalloc), however since this function is not polymorphic, only one instance is generated, and function pointers are used. Given that this function is called for any Rust-side allocation/deallocation, performance matters a lot, so making this function inlineable. This is discovered when doing helper inlining work, since it's discovered that even with helpers inlined, rust_helper_ symbols are still present in final vmlinux binary, and it turns out this function is inhibiting the inlining, and introducing indirect function calls. Signed-off-by: Gary Guo Acked-by: Danilo Krummrich Reviewed-by: Boqun Feng Reviewed-by: Alice Ryhl Link: https://lore.kernel.org/r/20250105194054.545201-4-gary@garyguo.net Signed-off-by: Miguel Ojeda --- rust/kernel/alloc/allocator.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'rust/kernel/alloc') diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs index 439985e29fbc..aa2dfa9dca4c 100644 --- a/rust/kernel/alloc/allocator.rs +++ b/rust/kernel/alloc/allocator.rs @@ -80,6 +80,7 @@ impl ReallocFunc { /// This method has the same guarantees as `Allocator::realloc`. Additionally /// - it accepts any pointer to a valid memory allocation allocated by this function. /// - memory allocated by this function remains valid until it is passed to this function. + #[inline] unsafe fn call( &self, ptr: Option>, -- cgit From 114ca41fe7922ce85fcac30fa2b06b42b4956520 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:04:34 +0000 Subject: rust: pin-init: move `InPlaceInit` and impls of `InPlaceWrite` into the kernel crate In order to make pin-init a standalone crate, move kernel-specific code directly into the kernel crate. This includes the `InPlaceInit` trait, its implementations and the implementations of `InPlaceWrite` for `Arc` and `UniqueArc`. All of these use the kernel's error type which will become unavailable in pin-init. Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-9-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/alloc/kbox.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'rust/kernel/alloc') diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index cb4ebea3b074..39a3ea7542da 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -15,7 +15,8 @@ use core::pin::Pin; use core::ptr::NonNull; use core::result::Result; -use crate::init::{InPlaceInit, InPlaceWrite, Init, PinInit}; +use crate::init::{InPlaceWrite, Init, PinInit}; +use crate::init_ext::InPlaceInit; use crate::types::ForeignOwnable; /// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. -- cgit From 9d29c682f00c3d8dd5727f6a350c4f6ecccc3913 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:04:38 +0000 Subject: rust: pin-init: move impl `Zeroable` for `Opaque` and `Option>` into the kernel crate In order to make pin-init a standalone crate, move kernel-specific code directly into the kernel crate. Since `Opaque` and `KBox` are part of the kernel, move their `Zeroable` implementation into the kernel crate. Signed-off-by: Benno Lossin Tested-by: Andreas Hindborg Reviewed-by: Fiona Behrens Link: https://lore.kernel.org/r/20250308110339.2997091-10-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/alloc/kbox.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'rust/kernel/alloc') diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 39a3ea7542da..9861433559dc 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -15,7 +15,7 @@ use core::pin::Pin; use core::ptr::NonNull; use core::result::Result; -use crate::init::{InPlaceWrite, Init, PinInit}; +use crate::init::{InPlaceWrite, Init, PinInit, Zeroable}; use crate::init_ext::InPlaceInit; use crate::types::ForeignOwnable; @@ -100,6 +100,12 @@ pub type VBox = Box; /// ``` pub type KVBox = Box; +// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee). +// +// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant and there +// is no problem with a VTABLE pointer being null. +unsafe impl Zeroable for Option> {} + // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. unsafe impl Send for Box where -- cgit From 5657c3a9faf6c1243cecc9314244c92bfcd1ecad Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:04:43 +0000 Subject: rust: add `ZeroableOption` and implement it instead of `Zeroable` for `Option>` When making pin-init its own crate, `Zeroable` will no longer be defined by the kernel crate and thus implementing it for `Option>` is no longer possible due to the orphan rule. For this reason introduce a new `ZeroableOption` trait that circumvents this problem. Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Reviewed-by: Andreas Hindborg Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-11-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/alloc/kbox.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rust/kernel/alloc') diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 9861433559dc..07150c038e3f 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -15,7 +15,7 @@ use core::pin::Pin; use core::ptr::NonNull; use core::result::Result; -use crate::init::{InPlaceWrite, Init, PinInit, Zeroable}; +use crate::init::{InPlaceWrite, Init, PinInit, ZeroableOption}; use crate::init_ext::InPlaceInit; use crate::types::ForeignOwnable; @@ -104,7 +104,7 @@ pub type KVBox = Box; // // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant and there // is no problem with a VTABLE pointer being null. -unsafe impl Zeroable for Option> {} +unsafe impl ZeroableOption for Box {} // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. unsafe impl Send for Box -- cgit From dbd5058ba60c3499b24a7133a4e2e24dba6ea77b Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:05:09 +0000 Subject: rust: make pin-init its own crate Rename relative paths inside of the crate to still refer to the same items, also rename paths inside of the kernel crate and adjust the build system to build the crate. [ Remove the `expect` (and thus the `lint_reasons` feature) since the tree now uses `quote!` from `rust/macros/export.rs`. Remove the `TokenStream` import removal, since it is now used as well. In addition, temporarily (i.e. just for this commit) use an `--extern force:alloc` to prevent an unknown `new_uninit` error in the `rustdoc` target. For context, please see a similar case in: https://lore.kernel.org/lkml/20240422090644.525520-1-ojeda@kernel.org/ And adjusted the message above. - Miguel ] Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-16-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/alloc/kbox.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rust/kernel/alloc') diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 07150c038e3f..e6200cd1d06d 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -15,9 +15,9 @@ use core::pin::Pin; use core::ptr::NonNull; use core::result::Result; -use crate::init::{InPlaceWrite, Init, PinInit, ZeroableOption}; -use crate::init_ext::InPlaceInit; +use crate::init::InPlaceInit; use crate::types::ForeignOwnable; +use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption}; /// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. /// -- cgit From b4fecceee29e2a6453ac746e70c16fe7f70babf9 Mon Sep 17 00:00:00 2001 From: Andreas Hindborg Date: Sun, 9 Mar 2025 16:19:00 +0100 Subject: rust: alloc: add `Box::into_pin` Add an associated function to convert a `Box` into a `Pin>`. Acked-by: Danilo Krummrich Reviewed-by: Benno Lossin Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20250309-hrtimer-v3-v6-12-rc2-v12-9-73586e2bd5f1@kernel.org Signed-off-by: Andreas Hindborg --- rust/kernel/alloc/kbox.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'rust/kernel/alloc') diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index cb4ebea3b074..9da4a32e60bc 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -245,6 +245,12 @@ where Ok(Self::new(x, flags)?.into()) } + /// Convert a [`Box`] to a [`Pin>`]. If `T` does not implement + /// [`Unpin`], then `x` will be pinned in memory and can't be moved. + pub fn into_pin(this: Self) -> Pin { + this.into() + } + /// Forgets the contents (does not run the destructor), but keeps the allocation. fn forget_contents(this: Self) -> Box, A> { let ptr = Self::into_raw(this); -- cgit