All of lore.kernel.org
 help / color / mirror / Atom feed
From: Danilo Krummrich <dakr@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
Cc: ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com,
	boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com,
	benno.lossin@proton.me, a.hindborg@samsung.com,
	akpm@linux-foundation.org, daniel.almeida@collabora.com,
	faith.ekstrand@collabora.com, boris.brezillon@collabora.com,
	lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com,
	acurrid@nvidia.com, cjia@nvidia.com, jhubbard@nvidia.com,
	airlied@redhat.com, ajanulgu@redhat.com, lyude@redhat.com,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	linux-mm@kvack.org
Subject: Re: [PATCH v3 09/25] rust: alloc: implement kernel `Box`
Date: Thu, 1 Aug 2024 14:45:38 +0200	[thread overview]
Message-ID: <ZquDcoPg2CzlPbpU@pollux> (raw)
In-Reply-To: <CAH5fLggjs8t2c1GVFdQu6gULjG_oYx7299m4NedQFS+hOgFfTw@mail.gmail.com>

On Thu, Aug 01, 2024 at 10:55:51AM +0200, Alice Ryhl wrote:
> On Thu, Aug 1, 2024 at 2:07 AM Danilo Krummrich <dakr@kernel.org> wrote:
> >
> > `Box` provides the simplest way to allocate memory for a generic type
> > with one of the kernel's allocators, e.g. `Kmalloc`, `Vmalloc` or
> > `KVmalloc`.
> >
> > In contrast to Rust's `Box` type, the kernel `Box` type considers the
> > kernel's GFP flags for all appropriate functions, always reports
> > allocation failures through `Result<_, AllocError>` and remains
> > independent from unstable features.
> >
> > Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> >
> > [...]
> >
> > +    /// Constructs a `Box<T, A>` from a raw pointer.
> > +    ///
> > +    /// # Safety
> > +    ///
> > +    /// `raw` must point to valid memory, previously allocated with `A`, and at least the size of
> > +    /// type `T`.
> > +    #[inline]
> > +    pub const unsafe fn from_raw_alloc(raw: *mut T, alloc: PhantomData<A>) -> Self {
> > +        // SAFETY: Safe by the requirements of this function.
> > +        Box(unsafe { Unique::new_unchecked(raw) }, alloc)
> > +    }
> 
> I don't think it makes sense to take the PhantomData as a parameter.
> You can always create a PhantomData value out of thin air.
> 
> Box(unsafe { Unique::new_unchecked(raw) }, PhantomData)
> 
> > +    /// Consumes the `Box<T, A>`, returning a wrapped raw pointer and `PhantomData` of the allocator
> > +    /// it was allocated with.
> > +    pub fn into_raw_alloc(b: Self) -> (*mut T, PhantomData<A>) {
> > +        let b = ManuallyDrop::new(b);
> > +        let alloc = unsafe { ptr::read(&b.1) };
> > +        (b.0.as_ptr(), alloc)
> > +    }
> 
> I don't think there's any need to have this function. The caller can
> always create the PhantomData themselves. I would just keep into_raw
> only.

Agreed, I actually intended to remove this one and the above.

> 
> > +    /// Converts a `Box<T>` into a `Pin<Box<T>>`.
> > +    #[inline]
> > +    pub fn into_pin(b: Self) -> Pin<Self>
> > +    where
> > +        A: 'static,
> > +    {
> > +        // SAFETY: It's not possible to move or replace the insides of a `Pin<Box<T>>` when
> > +        // `T: !Unpin`, so it's safe to pin it directly without any additional requirements.
> > +        unsafe { Pin::new_unchecked(b) }
> > +    }
> 
> In the standard library, this functionality is provided using the From
> trait rather than an inherent method. I think it makes sense to match
> std here.

I already provide `impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>` in this patch,
which just calls `Box::into_pin`.

> 
> > +impl<T, A> Drop for Box<T, A>
> > +where
> > +    T: ?Sized,
> > +    A: Allocator,
> > +{
> > +    fn drop(&mut self) {
> > +        let ptr = self.0.as_ptr();
> > +
> > +        // SAFETY: We need to drop `self.0` in place, before we free the backing memory.
> > +        unsafe { core::ptr::drop_in_place(ptr) };
> > +
> > +        // SAFETY: `ptr` is always properly aligned, dereferenceable and points to an initialized
> > +        // instance of `T`.
> > +        if unsafe { core::mem::size_of_val(&*ptr) } != 0 {
> > +            // SAFETY: `ptr` was previously allocated with `A`.
> > +            unsafe { A::free(self.0.as_non_null().cast()) };
> > +        }
> 
> You just destroyed the value by calling `drop_in_place`, so `ptr` no
> longer points at an initialized instance of `T`. Please compute
> whether the allocation has non-zero size before you call
> `drop_in_place`.

Huh! Good catch. No idea how I missed that.

> 
> Also, in normal Rust this code would leak the allocation on panic in
> the destructor. We may not care, but it's worth taking into account if
> anybody else copies this code to a different project with a different
> panic configuration.

I can add a corresponding note.

> 
> > +impl<T: 'static, A> ForeignOwnable for crate::alloc::Box<T, A>
> > +where
> > +    A: Allocator,
> > +{
> > +    type Borrowed<'a> = &'a T;
> > +
> > +    fn into_foreign(self) -> *const core::ffi::c_void {
> > +        crate::alloc::Box::into_raw(self) as _
> > +    }
> > +
> > +    unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T {
> > +        // SAFETY: The safety requirements for this function ensure that the object is still alive,
> > +        // so it is safe to dereference the raw pointer.
> > +        // The safety requirements of `from_foreign` also ensure that the object remains alive for
> > +        // the lifetime of the returned value.
> > +        unsafe { &*ptr.cast() }
> > +    }
> > +
> > +    unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
> > +        // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
> > +        // call to `Self::into_foreign`.
> > +        unsafe { crate::alloc::Box::from_raw(ptr as _) }
> > +    }
> > +}
> 
> You may want to also implement ForeignOwnable for Pin<Box<T>>. See:
> https://lore.kernel.org/all/20240730-foreign-ownable-pin-box-v1-1-b1d70cdae541@google.com/

Yeah, I think I've also seen another patch that it about to add a function to
convert a `Box` back into uninit state.

Depending how fast you need ForeignOwnable for Pin<Box<T>>, do you prefer to
contribute a corresponding patch to this series?

> 
> Alice
> 

  reply	other threads:[~2024-08-01 12:45 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-01  0:01 [PATCH v3 00/25] Generic `Allocator` support for Rust Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 01/25] rust: alloc: add `Allocator` trait Danilo Krummrich
2024-08-01  8:19   ` Alice Ryhl
2024-08-01 12:26     ` Danilo Krummrich
2024-08-01 14:25       ` Alice Ryhl
2024-08-01 15:09         ` Danilo Krummrich
2024-08-04  6:21   ` Boqun Feng
2024-08-04 12:29     ` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 02/25] rust: alloc: separate `aligned_size` from `krealloc_aligned` Danilo Krummrich
2024-08-01  8:21   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 03/25] rust: alloc: rename `KernelAllocator` to `Kmalloc` Danilo Krummrich
2024-08-01  8:21   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 04/25] rust: alloc: implement `Allocator` for `Kmalloc` Danilo Krummrich
2024-08-01  8:28   ` Alice Ryhl
2024-08-01 12:30     ` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 05/25] rust: alloc: add module `allocator_test` Danilo Krummrich
2024-08-01  8:41   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 06/25] rust: alloc: implement `Vmalloc` allocator Danilo Krummrich
2024-08-01  8:43   ` Alice Ryhl
2024-08-04  6:44   ` Boqun Feng
2024-08-04 12:41     ` Danilo Krummrich
2024-08-04 15:16       ` Danilo Krummrich
2024-08-04 17:39         ` Danilo Krummrich
2024-08-04 23:57           ` Boqun Feng
2024-08-05  0:54             ` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 07/25] rust: alloc: implement `KVmalloc` allocator Danilo Krummrich
2024-08-01  8:43   ` Alice Ryhl
2024-08-01 12:31     ` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 08/25] rust: types: implement `Unique<T>` Danilo Krummrich
2024-08-01  8:45   ` Alice Ryhl
2024-08-04  6:54   ` Boqun Feng
2024-08-01  0:02 ` [PATCH v3 09/25] rust: alloc: implement kernel `Box` Danilo Krummrich
2024-08-01  8:55   ` Alice Ryhl
2024-08-01 12:45     ` Danilo Krummrich [this message]
2024-08-01 12:48       ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 10/25] rust: treewide: switch to our kernel `Box` type Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 11/25] rust: alloc: remove `BoxExt` extension Danilo Krummrich
2024-08-01 14:53   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 12/25] rust: alloc: add `Box` to prelude Danilo Krummrich
2024-08-01 14:54   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 13/25] rust: alloc: import kernel `Box` type in types.rs Danilo Krummrich
2024-08-01 14:54   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 14/25] rust: alloc: import kernel `Box` type in init.rs Danilo Krummrich
2024-08-01 14:55   ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 15/25] rust: alloc: implement kernel `Vec` type Danilo Krummrich
2024-08-01 15:05   ` Alice Ryhl
2024-08-01 15:27     ` Danilo Krummrich
2024-08-01 15:31       ` Alice Ryhl
2024-08-01 15:46         ` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 16/25] rust: alloc: implement `IntoIterator` for `Vec` Danilo Krummrich
2024-08-01 15:07   ` Alice Ryhl
2024-08-01 15:30     ` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 17/25] rust: alloc: implement `collect` for `IntoIter` Danilo Krummrich
2024-08-01 15:10   ` Alice Ryhl
2024-08-01 15:37     ` Danilo Krummrich
2024-08-02  7:08       ` Alice Ryhl
2024-08-02 12:02         ` Danilo Krummrich
2024-08-02 12:08           ` Alice Ryhl
2024-08-01  0:02 ` [PATCH v3 18/25] rust: treewide: switch to the kernel `Vec` type Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 19/25] rust: alloc: remove `VecExt` extension Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 20/25] rust: alloc: add `Vec` to prelude Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 21/25] rust: alloc: remove `GlobalAlloc` and `krealloc_aligned` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 22/25] rust: error: use `core::alloc::LayoutError` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 23/25] rust: str: test: replace `alloc::format` Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 24/25] rust: alloc: update module comment of alloc.rs Danilo Krummrich
2024-08-01  0:02 ` [PATCH v3 25/25] kbuild: rust: remove the `alloc` crate Danilo Krummrich

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=ZquDcoPg2CzlPbpU@pollux \
    --to=dakr@kernel.org \
    --cc=a.hindborg@samsung.com \
    --cc=acurrid@nvidia.com \
    --cc=airlied@redhat.com \
    --cc=ajanulgu@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=boris.brezillon@collabora.com \
    --cc=cjia@nvidia.com \
    --cc=daniel.almeida@collabora.com \
    --cc=faith.ekstrand@collabora.com \
    --cc=gary@garyguo.net \
    --cc=jhubbard@nvidia.com \
    --cc=lina@asahilina.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lyude@redhat.com \
    --cc=mcanal@igalia.com \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@gmail.com \
    --cc=zhiw@nvidia.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.