* [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl @ 2023-06-22 19:24 Björn Roy Baron via B4 Relay 2023-06-23 1:07 ` Martin Rodriguez Reboredo 2023-06-23 17:35 ` Boqun Feng 0 siblings, 2 replies; 6+ messages in thread From: Björn Roy Baron via B4 Relay @ 2023-06-22 19:24 UTC (permalink / raw) To: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng, Gary Guo, Benno Lossin Cc: rust-for-linux, linux-kernel, Björn Roy Baron From: Björn Roy Baron <bjorn3_gh@protonmail.com> While there are default impls for these methods, using the respective C api's is faster. Currently neither the existing nor these new GlobalAlloc method implementations are actually called. Instead the __rust_* function defined below the GlobalAlloc impl are used. With rustc 1.71 these functions will be gone and all allocation calls will go through the GlobalAlloc implementation. Link: https://github.com/Rust-for-Linux/linux/issues/68 Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com> --- rust/kernel/allocator.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs index 397a3dd57a9b..e0a27b1326b5 100644 --- a/rust/kernel/allocator.rs +++ b/rust/kernel/allocator.rs @@ -21,6 +21,26 @@ unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { bindings::kfree(ptr as *const core::ffi::c_void); } } + + unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { + unsafe { + bindings::krealloc( + ptr as *const core::ffi::c_void, + new_size, + bindings::GFP_KERNEL, + ) as *mut u8 + } + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + unsafe { + bindings::krealloc( + core::ptr::null(), + layout.size(), + bindings::GFP_KERNEL | bindings::__GFP_ZERO, + ) as *mut u8 + } + } } #[global_allocator] --- base-commit: d2e3115d717197cb2bc020dd1f06b06538474ac3 change-id: 20230622-global_alloc_methods-abf5b5e38dba Best regards, -- Björn Roy Baron <bjorn3_gh@protonmail.com> ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl 2023-06-22 19:24 [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl Björn Roy Baron via B4 Relay @ 2023-06-23 1:07 ` Martin Rodriguez Reboredo 2023-06-23 17:35 ` Boqun Feng 1 sibling, 0 replies; 6+ messages in thread From: Martin Rodriguez Reboredo @ 2023-06-23 1:07 UTC (permalink / raw) To: bjorn3_gh, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng, Gary Guo, Benno Lossin Cc: rust-for-linux, linux-kernel On 6/22/23 16:24, Björn Roy Baron via B4 Relay wrote: > From: Björn Roy Baron <bjorn3_gh@protonmail.com> > > While there are default impls for these methods, using the respective C > api's is faster. Currently neither the existing nor these new > GlobalAlloc method implementations are actually called. Instead the > __rust_* function defined below the GlobalAlloc impl are used. With > rustc 1.71 these functions will be gone and all allocation calls will go > through the GlobalAlloc implementation. > > Link: https://github.com/Rust-for-Linux/linux/issues/68 > Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com> > --- > [...] Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl 2023-06-22 19:24 [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl Björn Roy Baron via B4 Relay 2023-06-23 1:07 ` Martin Rodriguez Reboredo @ 2023-06-23 17:35 ` Boqun Feng 2023-06-24 14:40 ` Björn Roy Baron 2023-06-25 20:39 ` Gary Guo 1 sibling, 2 replies; 6+ messages in thread From: Boqun Feng @ 2023-06-23 17:35 UTC (permalink / raw) To: bjorn3_gh Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Gary Guo, Benno Lossin, rust-for-linux, linux-kernel On Thu, Jun 22, 2023 at 09:24:40PM +0200, Björn Roy Baron via B4 Relay wrote: > From: Björn Roy Baron <bjorn3_gh@protonmail.com> > > While there are default impls for these methods, using the respective C > api's is faster. Currently neither the existing nor these new > GlobalAlloc method implementations are actually called. Instead the > __rust_* function defined below the GlobalAlloc impl are used. With > rustc 1.71 these functions will be gone and all allocation calls will go > through the GlobalAlloc implementation. > > Link: https://github.com/Rust-for-Linux/linux/issues/68 Nice! Although I think we need to do the simialr size adjustment as: https://lore.kernel.org/rust-for-linux/20230613164258.3831917-1-boqun.feng@gmail.com/ so I applied your patch onto my patch and came up with the following: --------------------------------->8 diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs index ce7a06bf7589..af723c2924dc 100644 --- a/rust/kernel/allocator.rs +++ b/rust/kernel/allocator.rs @@ -9,8 +9,17 @@ struct KernelAllocator; -unsafe impl GlobalAlloc for KernelAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +impl KernelAllocator { + /// # Safety + /// + /// * `ptr` can be either null or a pointer which has been allocated by this allocator. + /// * `layout` must have a non-zero size. + unsafe fn krealloc_with_flags( + &self, + ptr: *mut u8, + layout: Layout, + flags: bindings::gfp_t, + ) -> *mut u8 { // Customized layouts from `Layout::from_size_align()` can have size < align, so pads first. let layout = layout.pad_to_align(); @@ -26,9 +35,22 @@ unsafe fn alloc(&self, layout: Layout) -> *mut u8 { size = size.next_power_of_two(); } - // `krealloc()` is used instead of `kmalloc()` because the latter is - // an inline function and cannot be bound to as a result. - unsafe { bindings::krealloc(ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 } + // SAFETY: + // + // * `ptr` is either null or a pointer returned from a previous k{re}alloc() by the function + // safety requirement. + // + // * `size` is greater than 0 since it's either a `layout.size()` (which cannot be zero + // according to the function safety requirement) or a result from `next_power_of_two()`. + unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags) as *mut u8 } + } +} + +unsafe impl GlobalAlloc for KernelAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety + // requirement. + unsafe { self.krealloc_with_flags(ptr::null_mut(), layout, bindings::GFP_KERNEL) } } unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { @@ -37,23 +59,30 @@ unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { } } - unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { - unsafe { - bindings::krealloc( - ptr as *const core::ffi::c_void, - new_size, - bindings::GFP_KERNEL, - ) as *mut u8 - } + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + // SAFETY: + // * `new_size` when rounded up to the nearest multiple of `layout.align()`, will not + // overflow `isize` by the function safety requirement. + // * `layout.align()` is a proper alignment (i.e. not zero and must be a power of two). + let layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + + // SAFETY: + // * `ptr` is either null or a pointer allocated by this allocator by function safety + // requirement. + // * the size of `layout` is not zero because `new_size` is not zero by function safety + // requirement. + unsafe { self.krealloc_with_flags(ptr, layout, bindings::GFP_KERNEL) } } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety + // requirement. unsafe { - bindings::krealloc( - core::ptr::null(), - layout.size(), + self.krealloc_with_flags( + ptr::null_mut(), + layout, bindings::GFP_KERNEL | bindings::__GFP_ZERO, - ) as *mut u8 + ) } } } Regards, Boqun > Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com> > --- > rust/kernel/allocator.rs | 20 ++++++++++++++++++++ > 1 file changed, 20 insertions(+) > > diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs > index 397a3dd57a9b..e0a27b1326b5 100644 > --- a/rust/kernel/allocator.rs > +++ b/rust/kernel/allocator.rs > @@ -21,6 +21,26 @@ unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { > bindings::kfree(ptr as *const core::ffi::c_void); > } > } > + > + unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { > + unsafe { > + bindings::krealloc( > + ptr as *const core::ffi::c_void, > + new_size, > + bindings::GFP_KERNEL, > + ) as *mut u8 > + } > + } > + > + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { > + unsafe { > + bindings::krealloc( > + core::ptr::null(), > + layout.size(), > + bindings::GFP_KERNEL | bindings::__GFP_ZERO, > + ) as *mut u8 > + } > + } > } > > #[global_allocator] > > --- > base-commit: d2e3115d717197cb2bc020dd1f06b06538474ac3 > change-id: 20230622-global_alloc_methods-abf5b5e38dba > > Best regards, > -- > Björn Roy Baron <bjorn3_gh@protonmail.com> > ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl 2023-06-23 17:35 ` Boqun Feng @ 2023-06-24 14:40 ` Björn Roy Baron 2023-06-25 23:13 ` Boqun Feng 2023-06-25 20:39 ` Gary Guo 1 sibling, 1 reply; 6+ messages in thread From: Björn Roy Baron @ 2023-06-24 14:40 UTC (permalink / raw) To: Boqun Feng Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Gary Guo, Benno Lossin, rust-for-linux, linux-kernel On Friday, June 23rd, 2023 at 19:35, Boqun Feng <boqun.feng@gmail.com> wrote: > On Thu, Jun 22, 2023 at 09:24:40PM +0200, Björn Roy Baron via B4 Relay wrote: > > > From: Björn Roy Baron bjorn3_gh@protonmail.com > > > > While there are default impls for these methods, using the respective C > > api's is faster. Currently neither the existing nor these new > > GlobalAlloc method implementations are actually called. Instead the > > _rust* function defined below the GlobalAlloc impl are used. With > > rustc 1.71 these functions will be gone and all allocation calls will go > > through the GlobalAlloc implementation. > > > > Link: https://github.com/Rust-for-Linux/linux/issues/68 > > > Nice! Although I think we need to do the simialr size adjustment as: > > https://lore.kernel.org/rust-for-linux/20230613164258.3831917-1-boqun.feng@gmail.com/ > > so I applied your patch onto my patch and came up with the following: Right. That patch LGTM. Cheers, Björn ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl 2023-06-24 14:40 ` Björn Roy Baron @ 2023-06-25 23:13 ` Boqun Feng 0 siblings, 0 replies; 6+ messages in thread From: Boqun Feng @ 2023-06-25 23:13 UTC (permalink / raw) To: Björn Roy Baron Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Gary Guo, Benno Lossin, rust-for-linux, linux-kernel On Sat, Jun 24, 2023 at 02:40:23PM +0000, Björn Roy Baron wrote: > On Friday, June 23rd, 2023 at 19:35, Boqun Feng <boqun.feng@gmail.com> wrote: > > > On Thu, Jun 22, 2023 at 09:24:40PM +0200, Björn Roy Baron via B4 Relay wrote: > > > > > From: Björn Roy Baron bjorn3_gh@protonmail.com > > > > > > While there are default impls for these methods, using the respective C > > > api's is faster. Currently neither the existing nor these new > > > GlobalAlloc method implementations are actually called. Instead the > > > _rust* function defined below the GlobalAlloc impl are used. With > > > rustc 1.71 these functions will be gone and all allocation calls will go > > > through the GlobalAlloc implementation. > > > > > > Link: https://github.com/Rust-for-Linux/linux/issues/68 > > > > > > Nice! Although I think we need to do the simialr size adjustment as: > > > > https://lore.kernel.org/rust-for-linux/20230613164258.3831917-1-boqun.feng@gmail.com/ > > > > so I applied your patch onto my patch and came up with the following: > > Right. That patch LGTM. > Thank you and Gary for the diff review, I will fold it into your original patch and resend. Regards, Boqun > Cheers, > Björn ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl 2023-06-23 17:35 ` Boqun Feng 2023-06-24 14:40 ` Björn Roy Baron @ 2023-06-25 20:39 ` Gary Guo 1 sibling, 0 replies; 6+ messages in thread From: Gary Guo @ 2023-06-25 20:39 UTC (permalink / raw) To: Boqun Feng Cc: bjorn3_gh, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Benno Lossin, rust-for-linux, linux-kernel On Fri, 23 Jun 2023 10:35:00 -0700 Boqun Feng <boqun.feng@gmail.com> wrote: > On Thu, Jun 22, 2023 at 09:24:40PM +0200, Björn Roy Baron via B4 Relay wrote: > > From: Björn Roy Baron <bjorn3_gh@protonmail.com> > > > > While there are default impls for these methods, using the respective C > > api's is faster. Currently neither the existing nor these new > > GlobalAlloc method implementations are actually called. Instead the > > __rust_* function defined below the GlobalAlloc impl are used. With > > rustc 1.71 these functions will be gone and all allocation calls will go > > through the GlobalAlloc implementation. > > > > Link: https://github.com/Rust-for-Linux/linux/issues/68 > > Nice! Although I think we need to do the simialr size adjustment as: > > https://lore.kernel.org/rust-for-linux/20230613164258.3831917-1-boqun.feng@gmail.com/ > > so I applied your patch onto my patch and came up with the following: The diff LGTM. > > --------------------------------->8 > diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs > index ce7a06bf7589..af723c2924dc 100644 > --- a/rust/kernel/allocator.rs > +++ b/rust/kernel/allocator.rs > @@ -9,8 +9,17 @@ > > struct KernelAllocator; > > -unsafe impl GlobalAlloc for KernelAllocator { > - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { > +impl KernelAllocator { > + /// # Safety > + /// > + /// * `ptr` can be either null or a pointer which has been allocated by this allocator. > + /// * `layout` must have a non-zero size. > + unsafe fn krealloc_with_flags( > + &self, > + ptr: *mut u8, > + layout: Layout, > + flags: bindings::gfp_t, > + ) -> *mut u8 { > // Customized layouts from `Layout::from_size_align()` can have size < align, so pads first. > let layout = layout.pad_to_align(); > > @@ -26,9 +35,22 @@ unsafe fn alloc(&self, layout: Layout) -> *mut u8 { > size = size.next_power_of_two(); > } > > - // `krealloc()` is used instead of `kmalloc()` because the latter is > - // an inline function and cannot be bound to as a result. > - unsafe { bindings::krealloc(ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 } > + // SAFETY: > + // > + // * `ptr` is either null or a pointer returned from a previous k{re}alloc() by the function > + // safety requirement. > + // > + // * `size` is greater than 0 since it's either a `layout.size()` (which cannot be zero > + // according to the function safety requirement) or a result from `next_power_of_two()`. > + unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags) as *mut u8 } > + } > +} > + > +unsafe impl GlobalAlloc for KernelAllocator { > + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { > + // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety > + // requirement. > + unsafe { self.krealloc_with_flags(ptr::null_mut(), layout, bindings::GFP_KERNEL) } > } > > unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { > @@ -37,23 +59,30 @@ unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { > } > } > > - unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { > - unsafe { > - bindings::krealloc( > - ptr as *const core::ffi::c_void, > - new_size, > - bindings::GFP_KERNEL, > - ) as *mut u8 > - } > + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { > + // SAFETY: > + // * `new_size` when rounded up to the nearest multiple of `layout.align()`, will not > + // overflow `isize` by the function safety requirement. > + // * `layout.align()` is a proper alignment (i.e. not zero and must be a power of two). > + let layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; > + > + // SAFETY: > + // * `ptr` is either null or a pointer allocated by this allocator by function safety > + // requirement. > + // * the size of `layout` is not zero because `new_size` is not zero by function safety > + // requirement. > + unsafe { self.krealloc_with_flags(ptr, layout, bindings::GFP_KERNEL) } > } > > unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { > + // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety > + // requirement. > unsafe { > - bindings::krealloc( > - core::ptr::null(), > - layout.size(), > + self.krealloc_with_flags( > + ptr::null_mut(), > + layout, > bindings::GFP_KERNEL | bindings::__GFP_ZERO, > - ) as *mut u8 > + ) > } > } > } > > > Regards, > Boqun > > > Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com> > > --- > > rust/kernel/allocator.rs | 20 ++++++++++++++++++++ > > 1 file changed, 20 insertions(+) > > > > diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs > > index 397a3dd57a9b..e0a27b1326b5 100644 > > --- a/rust/kernel/allocator.rs > > +++ b/rust/kernel/allocator.rs > > @@ -21,6 +21,26 @@ unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { > > bindings::kfree(ptr as *const core::ffi::c_void); > > } > > } > > + > > + unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { > > + unsafe { > > + bindings::krealloc( > > + ptr as *const core::ffi::c_void, > > + new_size, > > + bindings::GFP_KERNEL, > > + ) as *mut u8 > > + } > > + } > > + > > + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { > > + unsafe { > > + bindings::krealloc( > > + core::ptr::null(), > > + layout.size(), > > + bindings::GFP_KERNEL | bindings::__GFP_ZERO, > > + ) as *mut u8 > > + } > > + } > > } > > > > #[global_allocator] > > > > --- > > base-commit: d2e3115d717197cb2bc020dd1f06b06538474ac3 > > change-id: 20230622-global_alloc_methods-abf5b5e38dba > > > > Best regards, > > -- > > Björn Roy Baron <bjorn3_gh@protonmail.com> > > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-06-25 23:14 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-06-22 19:24 [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl Björn Roy Baron via B4 Relay 2023-06-23 1:07 ` Martin Rodriguez Reboredo 2023-06-23 17:35 ` Boqun Feng 2023-06-24 14:40 ` Björn Roy Baron 2023-06-25 23:13 ` Boqun Feng 2023-06-25 20:39 ` Gary Guo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).