All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gary Guo <gary@garyguo.net>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: bjorn3_gh@protonmail.com, Miguel Ojeda <ojeda@kernel.org>,
	Alex Gaynor <alex.gaynor@gmail.com>,
	Wedson Almeida Filho <wedsonaf@gmail.com>,
	Benno Lossin <benno.lossin@proton.me>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl
Date: Sun, 25 Jun 2023 21:39:27 +0100	[thread overview]
Message-ID: <20230625213927.2e656905.gary@garyguo.net> (raw)
In-Reply-To: <ZJXXxEfzVza5Jzxj@boqun-archlinux>

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>
> >   


      parent reply	other threads:[~2023-06-25 20:39 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-22 19:24 [PATCH] rust: alloc: Add realloc and alloc_zeroed to the GlobalAlloc impl Björn Roy Baron
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
2023-06-24 14:40   ` Björn Roy Baron
2023-06-25 23:13     ` Boqun Feng
2023-06-25 20:39   ` Gary Guo [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230625213927.2e656905.gary@garyguo.net \
    --to=gary@garyguo.net \
    --cc=alex.gaynor@gmail.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.