rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init()
@ 2023-04-03 10:01 Asahi Lina
  2023-04-03 10:01 ` [PATCH v2 1/2] rust: sync: arc: Implement Arc<dyn Any + Send + Sync>::downcast() Asahi Lina
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Asahi Lina @ 2023-04-03 10:01 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron
  Cc: Andreas Hindborg, Vincenzo Palazzo, Martin Rodriguez Reboredo,
	Benno Lossin, rust-for-linux, linux-kernel, asahi, Asahi Lina

Hi everyone,

This short series is part of the set of dependencies for the drm/asahi
Apple M1/M2 GPU driver.

The two patches simply add two missing features to the kernel Arc
implementation which are present in the Rust std version: `Any`
downcasting and `assume_init()`.

Signed-off-by: Asahi Lina <lina@asahilina.net>
---
Changes in v2:
- #1: Moved the new function to a separate file, to keep the licensing
  clearer.
- #2: Replaced the safety comment with Benno's, from his pin-init series
  (we both wrote the same patch).
- Link to v1: https://lore.kernel.org/r/20230224-rust-arc-v1-0-568eea613a41@asahilina.net

---
Asahi Lina (2):
      rust: sync: arc: Implement Arc<dyn Any + Send + Sync>::downcast()
      rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init()
 rust/kernel/sync/arc.rs            | 13 +++++++++++++
 rust/kernel/sync/arc/std_vendor.rs | 28 ++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)
---
base-commit: fe15c26ee26efa11741a7b632e9f23b01aca4cc6
change-id: 20230224-rust-arc-ba3c26ed4e6a

Thank you,
~~ Lina


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] rust: sync: arc: Implement Arc<dyn Any + Send + Sync>::downcast()
  2023-04-03 10:01 [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Asahi Lina
@ 2023-04-03 10:01 ` Asahi Lina
  2023-04-03 10:01 ` [PATCH v2 2/2] rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init() Asahi Lina
  2023-04-10  3:47 ` [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Miguel Ojeda
  2 siblings, 0 replies; 5+ messages in thread
From: Asahi Lina @ 2023-04-03 10:01 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron
  Cc: Andreas Hindborg, Vincenzo Palazzo, Martin Rodriguez Reboredo,
	Benno Lossin, rust-for-linux, linux-kernel, asahi, Asahi Lina

This mirrors the standard library's alloc::sync::Arc::downcast().

Based on the Rust standard library implementation, ver 1.62.0,
licensed under "Apache-2.0 OR MIT", from:

    https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src

For copyright details, please see:

    https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT

Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Asahi Lina <lina@asahilina.net>
---
 rust/kernel/sync/arc.rs            |  2 ++
 rust/kernel/sync/arc/std_vendor.rs | 28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index f2f1c83d72ba..b904ed898d3a 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -522,3 +522,5 @@ impl<T: ?Sized> DerefMut for UniqueArc<T> {
         unsafe { &mut self.inner.ptr.as_mut().data }
     }
 }
+
+mod std_vendor;
diff --git a/rust/kernel/sync/arc/std_vendor.rs b/rust/kernel/sync/arc/std_vendor.rs
new file mode 100644
index 000000000000..a66a0c2831b3
--- /dev/null
+++ b/rust/kernel/sync/arc/std_vendor.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+//! The contents of this file come from the Rust standard library, hosted in
+//! the <https://github.com/rust-lang/rust> repository, licensed under
+//! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
+//! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
+
+use crate::sync::{arc::ArcInner, Arc};
+use core::any::Any;
+
+impl Arc<dyn Any + Send + Sync> {
+    /// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
+    pub fn downcast<T>(self) -> core::result::Result<Arc<T>, Self>
+    where
+        T: Any + Send + Sync,
+    {
+        if (*self).is::<T>() {
+            // SAFETY: We have just checked that the type is correct, so we can cast the pointer.
+            unsafe {
+                let ptr = self.ptr.cast::<ArcInner<T>>();
+                core::mem::forget(self);
+                Ok(Arc::from_inner(ptr))
+            }
+        } else {
+            Err(self)
+        }
+    }
+}

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init()
  2023-04-03 10:01 [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Asahi Lina
  2023-04-03 10:01 ` [PATCH v2 1/2] rust: sync: arc: Implement Arc<dyn Any + Send + Sync>::downcast() Asahi Lina
@ 2023-04-03 10:01 ` Asahi Lina
  2023-04-03 15:26   ` Gary Guo
  2023-04-10  3:47 ` [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Miguel Ojeda
  2 siblings, 1 reply; 5+ messages in thread
From: Asahi Lina @ 2023-04-03 10:01 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron
  Cc: Andreas Hindborg, Vincenzo Palazzo, Martin Rodriguez Reboredo,
	Benno Lossin, rust-for-linux, linux-kernel, asahi, Asahi Lina

We can already create `UniqueArc<MaybeUninit<T>>` instances with
`UniqueArc::try_new_uninit()` and write to them with `write()`. Add
the missing unsafe `assume_init()` function to promote it to
`UniqueArc<T>`, so users can do piece-wise initialization of the
contents instead of doing it all at once as long as they keep the
invariants (the same requirements as `MaybeUninit::assume_init()`).

This mirrors the std `Arc::assume_init()` function. In the kernel,
since we have `UniqueArc`, arguably this only belongs there since most
use cases will initialize it immediately after creating it, before
demoting it to `Arc` to share it.

Co-authored-by: Benno Lossin <y86-dev@protonmail.com>
Signed-off-by: Benno Lossin <y86-dev@protonmail.com>
Signed-off-by: Asahi Lina <lina@asahilina.net>
---
 rust/kernel/sync/arc.rs | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index b904ed898d3a..b664b41e473d 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -489,6 +489,17 @@ impl<T> UniqueArc<MaybeUninit<T>> {
     /// Converts a `UniqueArc<MaybeUninit<T>>` into a `UniqueArc<T>` by writing a value into it.
     pub fn write(mut self, value: T) -> UniqueArc<T> {
         self.deref_mut().write(value);
+        // SAFETY: We have just written the contents fully.
+        unsafe { self.assume_init() }
+    }
+
+    /// Unsafely assume that `self` is initialized.
+    ///
+    /// # Safety
+    ///
+    /// The caller guarantees that the value behind this pointer has been initialized. It is
+    /// *immediate* UB to call this when the value is not initialized.
+    pub unsafe fn assume_init(self) -> UniqueArc<T> {
         let inner = ManuallyDrop::new(self).inner.ptr;
         UniqueArc {
             // SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (which won't be

-- 
2.40.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init()
  2023-04-03 10:01 ` [PATCH v2 2/2] rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init() Asahi Lina
@ 2023-04-03 15:26   ` Gary Guo
  0 siblings, 0 replies; 5+ messages in thread
From: Gary Guo @ 2023-04-03 15:26 UTC (permalink / raw)
  To: Asahi Lina
  Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Björn Roy Baron, Andreas Hindborg, Vincenzo Palazzo,
	Martin Rodriguez Reboredo, Benno Lossin, rust-for-linux,
	linux-kernel, asahi

On Mon, 03 Apr 2023 19:01:12 +0900
Asahi Lina <lina@asahilina.net> wrote:

> We can already create `UniqueArc<MaybeUninit<T>>` instances with
> `UniqueArc::try_new_uninit()` and write to them with `write()`. Add
> the missing unsafe `assume_init()` function to promote it to
> `UniqueArc<T>`, so users can do piece-wise initialization of the
> contents instead of doing it all at once as long as they keep the
> invariants (the same requirements as `MaybeUninit::assume_init()`).
> 
> This mirrors the std `Arc::assume_init()` function. In the kernel,
> since we have `UniqueArc`, arguably this only belongs there since most
> use cases will initialize it immediately after creating it, before
> demoting it to `Arc` to share it.
> 
> Co-authored-by: Benno Lossin <y86-dev@protonmail.com>
> Signed-off-by: Benno Lossin <y86-dev@protonmail.com>
> Signed-off-by: Asahi Lina <lina@asahilina.net>

Reviewed-by: Gary Guo <gary@garyguo.net>

> ---
>  rust/kernel/sync/arc.rs | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
> index b904ed898d3a..b664b41e473d 100644
> --- a/rust/kernel/sync/arc.rs
> +++ b/rust/kernel/sync/arc.rs
> @@ -489,6 +489,17 @@ impl<T> UniqueArc<MaybeUninit<T>> {
>      /// Converts a `UniqueArc<MaybeUninit<T>>` into a `UniqueArc<T>` by writing a value into it.
>      pub fn write(mut self, value: T) -> UniqueArc<T> {
>          self.deref_mut().write(value);
> +        // SAFETY: We have just written the contents fully.
> +        unsafe { self.assume_init() }
> +    }
> +
> +    /// Unsafely assume that `self` is initialized.
> +    ///
> +    /// # Safety
> +    ///
> +    /// The caller guarantees that the value behind this pointer has been initialized. It is
> +    /// *immediate* UB to call this when the value is not initialized.
> +    pub unsafe fn assume_init(self) -> UniqueArc<T> {
>          let inner = ManuallyDrop::new(self).inner.ptr;
>          UniqueArc {
>              // SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (which won't be
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init()
  2023-04-03 10:01 [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Asahi Lina
  2023-04-03 10:01 ` [PATCH v2 1/2] rust: sync: arc: Implement Arc<dyn Any + Send + Sync>::downcast() Asahi Lina
  2023-04-03 10:01 ` [PATCH v2 2/2] rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init() Asahi Lina
@ 2023-04-10  3:47 ` Miguel Ojeda
  2 siblings, 0 replies; 5+ messages in thread
From: Miguel Ojeda @ 2023-04-10  3:47 UTC (permalink / raw)
  To: Asahi Lina
  Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron, Andreas Hindborg,
	Vincenzo Palazzo, Martin Rodriguez Reboredo, Benno Lossin,
	rust-for-linux, linux-kernel, asahi

On Mon, Apr 3, 2023 at 12:01 PM Asahi Lina <lina@asahilina.net> wrote:
>
> Hi everyone,
>
> This short series is part of the set of dependencies for the drm/asahi
> Apple M1/M2 GPU driver.
>
> The two patches simply add two missing features to the kernel Arc
> implementation which are present in the Rust std version: `Any`
> downcasting and `assume_init()`.

Applied to `rust-next`. Thanks!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-04-10  3:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-03 10:01 [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Asahi Lina
2023-04-03 10:01 ` [PATCH v2 1/2] rust: sync: arc: Implement Arc<dyn Any + Send + Sync>::downcast() Asahi Lina
2023-04-03 10:01 ` [PATCH v2 2/2] rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init() Asahi Lina
2023-04-03 15:26   ` Gary Guo
2023-04-10  3:47 ` [PATCH v2 0/2] rust: sync: Arc: Any downcasting and assume_init() Miguel Ojeda

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