All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Hindborg <nmi@metaspace.dk>
To: Benno Lossin <y86-dev@protonmail.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Alice Ryhl" <alice@ryhl.io>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	patches@lists.linux.dev, "Alice Ryhl" <aliceryhl@google.com>,
	"Andreas Hindborg" <a.hindborg@samsung.com>
Subject: Re: [PATCH v6 14/15] rust: sync: reduce stack usage of `UniqueArc::try_new_uninit`
Date: Wed, 05 Apr 2023 23:59:01 +0200	[thread overview]
Message-ID: <87pm8irnw5.fsf@metaspace.dk> (raw)
In-Reply-To: <20230405193445.745024-15-y86-dev@protonmail.com>


Benno Lossin <y86-dev@protonmail.com> writes:

> `UniqueArc::try_new_uninit` calls `Arc::try_new(MaybeUninit::uninit())`.
> This results in the uninitialized memory being placed on the stack,
> which may be arbitrarily large due to the generic `T` and thus could
> cause a stack overflow for large types.
>
> Change the implementation to use the pin-init API which enables in-place
> initialization. In particular it avoids having to first construct and
> then move the uninitialized memory from the stack into the final location.
>
> Signed-off-by: Benno Lossin <y86-dev@protonmail.com>
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> Reviewed-by: Gary Guo <gary@garyguo.net>
> Cc: Andreas Hindborg <a.hindborg@samsung.com>
> ---

Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>

>  rust/kernel/lib.rs      |  1 -
>  rust/kernel/sync/arc.rs | 16 +++++++++++++---
>  2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index 821bd067151c..2d7606135ef6 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -28,7 +28,6 @@
>  #[cfg(not(CONFIG_RUST))]
>  compile_error!("Missing kernel configuration for conditional compilation");
>
> -#[allow(unused_extern_crates)]
>  // Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
>  extern crate self as kernel;
>
> diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> index 43a53fbe175d..d05caa723718 100644
> --- a/rust/kernel/sync/arc.rs
> +++ b/rust/kernel/sync/arc.rs
> @@ -18,7 +18,8 @@
>  use crate::{
>      bindings,
>      error::{self, Error},
> -    init::{InPlaceInit, Init, PinInit},
> +    init::{self, InPlaceInit, Init, PinInit},
> +    try_init,
>      types::{ForeignOwnable, Opaque},
>  };
>  use alloc::boxed::Box;
> @@ -30,6 +31,7 @@ use core::{
>      pin::Pin,
>      ptr::NonNull,
>  };
> +use macros::pin_data;
>
>  /// A reference-counted pointer to an instance of `T`.
>  ///
> @@ -122,6 +124,7 @@ pub struct Arc<T: ?Sized> {
>      _p: PhantomData<ArcInner<T>>,
>  }
>
> +#[pin_data]
>  #[repr(C)]
>  struct ArcInner<T: ?Sized> {
>      refcount: Opaque<bindings::refcount_t>,
> @@ -502,9 +505,16 @@ impl<T> UniqueArc<T> {
>
>      /// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet.
>      pub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>, AllocError> {
> -        Ok(UniqueArc::<MaybeUninit<T>> {
> +        // INVARIANT: The refcount is initialised to a non-zero value.
> +        let inner = Box::try_init::<AllocError>(try_init!(ArcInner {
> +            // SAFETY: There are no safety requirements for this FFI call.
> +            refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
> +            data <- init::uninit::<T, AllocError>(),
> +        }? AllocError))?;
> +        Ok(UniqueArc {
>              // INVARIANT: The newly-created object has a ref-count of 1.
> -            inner: Arc::try_new(MaybeUninit::uninit())?,
> +            // SAFETY: The pointer from the `Box` is valid.
> +            inner: unsafe { Arc::from_inner(Box::leak(inner).into()) },
>          })
>      }
>  }


  reply	other threads:[~2023-04-05 21:59 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-05 19:35 [PATCH v6 00/15] Rust pin-init API for pinned initialization of structs Benno Lossin
2023-04-05 19:35 ` [PATCH v6 01/15] rust: enable the `pin_macro` feature Benno Lossin
2023-04-05 20:45   ` Andreas Hindborg
2023-04-05 19:35 ` [PATCH v6 02/15] rust: macros: add `quote!` macro Benno Lossin
2023-04-05 19:35 ` [PATCH v6 03/15] rust: sync: change error type of constructor functions Benno Lossin
2023-04-05 19:35 ` [PATCH v6 04/15] rust: sync: add `assume_init` to `UniqueArc` Benno Lossin
2023-04-05 19:35 ` [PATCH v6 05/15] rust: types: add `Opaque::raw_get` Benno Lossin
2023-04-05 19:36 ` [PATCH v6 06/15] rust: add pin-init API core Benno Lossin
2023-04-05 21:04   ` Andreas Hindborg
2023-04-05 19:36 ` [PATCH v6 07/15] rust: init: add initialization macros Benno Lossin
2023-04-05 21:14   ` Andreas Hindborg
2023-04-05 19:36 ` [PATCH v6 08/15] rust: init/sync: add `InPlaceInit` trait to pin-initialize smart pointers Benno Lossin
2023-04-05 21:34   ` Andreas Hindborg
2023-04-05 19:36 ` [PATCH v6 09/15] rust: init: add `PinnedDrop` trait and macros Benno Lossin
2023-04-05 21:40   ` Andreas Hindborg
2023-04-05 19:36 ` [PATCH v6 10/15] rust: init: add `stack_pin_init!` macro Benno Lossin
2023-04-05 19:59   ` Gary Guo
2023-04-05 21:51   ` Andreas Hindborg
2023-04-05 19:36 ` [PATCH v6 11/15] rust: init: add `Zeroable` trait and `init::zeroed` function Benno Lossin
2023-04-05 22:08   ` Andreas Hindborg
2023-04-05 19:36 ` [PATCH v6 12/15] rust: prelude: add `pin-init` API items to prelude Benno Lossin
2023-04-05 19:36 ` [PATCH v6 13/15] rust: types: add common init-helper functions for `Opaque` Benno Lossin
2023-04-05 20:18   ` Gary Guo
2023-04-06  6:56   ` [PATCH v6.1] rust: types: add `Opaque::pin_init` Benno Lossin
2023-04-05 19:36 ` [PATCH v6 14/15] rust: sync: reduce stack usage of `UniqueArc::try_new_uninit` Benno Lossin
2023-04-05 21:59   ` Andreas Hindborg [this message]
2023-04-05 19:36 ` [PATCH v6 15/15] rust: sync: add functions for initializing `UniqueArc<MaybeUninit<T>>` Benno Lossin
2023-04-05 21:02 ` [PATCH v6 00/15] Rust pin-init API for pinned initialization of structs Boqun Feng
2023-04-05 21:06   ` Benno Lossin
2023-04-05 21:11     ` Boqun Feng

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=87pm8irnw5.fsf@metaspace.dk \
    --to=nmi@metaspace.dk \
    --cc=a.hindborg@samsung.com \
    --cc=alex.gaynor@gmail.com \
    --cc=alice@ryhl.io \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@gmail.com \
    --cc=y86-dev@protonmail.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.