[PATCH v10 1/5] rust: types: Add Ownable/Owned types

Oliver Mangold posted 5 patches 9 months, 1 week ago
There is a newer version of this series
[PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Oliver Mangold 9 months, 1 week ago
From: Asahi Lina <lina@asahilina.net>

By analogy to AlwaysRefCounted and ARef, an Ownable type is a (typically
C FFI) type that *may* be owned by Rust, but need not be. Unlike
AlwaysRefCounted, this mechanism expects the reference to be unique
within Rust, and does not allow cloning.

Conceptually, this is similar to a KBox<T>, except that it delegates
resource management to the T instead of using a generic allocator.

Link: https://lore.kernel.org/all/20250202-rust-page-v1-1-e3170d7fe55e@asahilina.net/
Signed-off-by: Asahi Lina <lina@asahilina.net>
[ om:
  - split code into separate file and `pub use` it from types.rs
  - make from_raw() and into_raw() public
  - fixes to documentation
]
Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
---
 rust/kernel/types.rs         |   3 ++
 rust/kernel/types/ownable.rs | 117 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index 9d0471afc9648f2973235488b441eb109069adb1..5d8a99dcba4bf733107635bf3f0c15840ec33e4c 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -11,6 +11,9 @@
 };
 use pin_init::{PinInit, Zeroable};
 
+pub mod ownable;
+pub use ownable::{Ownable, OwnableMut, Owned};
+
 /// Used to transfer ownership to and from foreign (non-Rust) languages.
 ///
 /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
new file mode 100644
index 0000000000000000000000000000000000000000..52e7a69019f1e2bbbe3cf715651b67a5a5c7c13d
--- /dev/null
+++ b/rust/kernel/types/ownable.rs
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Owned reference types.
+
+use core::{
+    marker::PhantomData,
+    mem::ManuallyDrop,
+    ops::{Deref, DerefMut},
+    ptr::NonNull,
+};
+
+/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
+///
+/// It allows such types to define their own custom destructor function to be called when
+/// a Rust-owned reference is dropped.
+///
+/// This is usually implemented by wrappers to existing structures on the C side of the code.
+///
+/// # Safety
+///
+/// Implementers must ensure that:
+/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
+///   until the [`release()`](Ownable::release) trait method is called).
+/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
+///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
+///   while Rust owns it.
+pub unsafe trait Ownable {
+    /// Releases the object (frees it or returns it to foreign ownership).
+    ///
+    /// # Safety
+    ///
+    /// Callers must ensure that the object is no longer referenced after this call.
+    unsafe fn release(this: NonNull<Self>);
+}
+
+/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
+/// may be dereferenced into a `&mut T`.
+///
+/// # Safety
+///
+/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
+/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).
+pub unsafe trait OwnableMut: Ownable {}
+
+/// An owned reference to an ownable kernel object.
+///
+/// The object is automatically freed or released when an instance of [`Owned`] is
+/// dropped.
+///
+/// # Invariants
+///
+/// The pointer stored in `ptr` is valid for the lifetime of the [`Owned`] instance.
+pub struct Owned<T: Ownable> {
+    ptr: NonNull<T>,
+    _p: PhantomData<T>,
+}
+
+// SAFETY: It is safe to send `Owned<T>` to another thread when the underlying `T` is `Send` because
+// it effectively means sending a `&mut T` (which is safe because `T` is `Send`).
+unsafe impl<T: Ownable + Send> Send for Owned<T> {}
+
+// SAFETY: It is safe to send `&Owned<T>` to another thread when the underlying `T` is `Sync`
+// because it effectively means sharing `&T` (which is safe because `T` is `Sync`).
+unsafe impl<T: Ownable + Sync> Sync for Owned<T> {}
+
+impl<T: Ownable> Owned<T> {
+    /// Creates a new instance of [`Owned`].
+    ///
+    /// It takes over ownership of the underlying object.
+    ///
+    /// # Safety
+    ///
+    /// Callers must ensure that the underlying object is acquired and can be considered owned by
+    /// Rust.
+    pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
+        // INVARIANT: The safety requirements guarantee that the new instance now owns the
+        // reference.
+        Self {
+            ptr,
+            _p: PhantomData,
+        }
+    }
+
+    /// Consumes the [`Owned`], returning a raw pointer.
+    ///
+    /// This function does not actually relinquish ownership of the object.
+    /// After calling this function, the caller is responsible for ownership previously managed
+    /// by the [`Owned`].
+    pub fn into_raw(me: Self) -> NonNull<T> {
+        ManuallyDrop::new(me).ptr
+    }
+}
+
+impl<T: Ownable> Deref for Owned<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        // SAFETY: The type invariants guarantee that the object is valid.
+        unsafe { self.ptr.as_ref() }
+    }
+}
+
+impl<T: OwnableMut> DerefMut for Owned<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        // SAFETY: The type invariants guarantee that the object is valid,
+        // and that we can safely return a mutable reference to it.
+        unsafe { self.ptr.as_mut() }
+    }
+}
+
+impl<T: Ownable> Drop for Owned<T> {
+    fn drop(&mut self) {
+        // SAFETY: The type invariants guarantee that the `Owned` owns the object we're about to
+        // release.
+        unsafe { T::release(self.ptr) };
+    }
+}

-- 
2.49.0
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Benno Lossin 9 months ago
On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
> +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
> +///
> +/// It allows such types to define their own custom destructor function to be called when
> +/// a Rust-owned reference is dropped.
> +///
> +/// This is usually implemented by wrappers to existing structures on the C side of the code.

The docs should mention `AlwaysRefCounted` and when to use it instead of
this trait. We should probably also backlink from `AlwaysRefCounted` to
`Ownable`.

> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that:
> +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> +///   until the [`release()`](Ownable::release) trait method is called).

I don't immediately understand what this means. How about "Any value of
type `Self` needs to be stored as [`Owned<Self>`]."? And then ask in
`Owned::from_raw` for a pointer that is valid indefinitely (or at least
until `release` is called).

> +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> +///   while Rust owns it.

I feel like this requirement is better put on the `Owned::from_raw`
function.

> +pub unsafe trait Ownable {
> +    /// Releases the object (frees it or returns it to foreign ownership).
> +    ///
> +    /// # Safety
> +    ///
> +    /// Callers must ensure that the object is no longer referenced after this call.
> +    unsafe fn release(this: NonNull<Self>);
> +}
> +
> +/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
> +/// may be dereferenced into a `&mut T`.

The "A subtrait of Ownable that asserts" sounds a bit clumsy to me, how
about "Type where [`Owned<Self>`] derefs to `&mut Self`."?

> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
> +/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).

I don't like that we put this requirement here, since it's actually
something that should be asserted by `Owned::from_raw`.
The reason for that is that anyone can call `Owned::from_raw` with a
pointer pointing to `Self` and there is no safety requirement on that
function that ensures the correctness of the `DerefMut` impl.

> +pub unsafe trait OwnableMut: Ownable {}

I don't like the name, but at the same time I also have no good
suggestion :( I'll think some more about it.

---
Cheers,
Benno
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Oliver Mangold 7 months, 3 weeks ago
On 250514 1132, Benno Lossin wrote:
> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
> 
> > +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> > +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> > +///   while Rust owns it.
> 
> I feel like this requirement is better put on the `Owned::from_raw`
> function.

Thinking about it some more, the problem I see here is that if the type
implements `OwnableMut` this requirement changes from "never mutate" to
"never access at all".

The safety requirements between `Ownable`, `OwnableMut`, `RefCounted`,
`OwnableRefCounted` and `AlwaysRefCounted` are interacting, but I agree
that, when looking at it a certain way, `Owned::from_raw()` is the place
where one would expect these to be. I'm not sure anymore what is best here
:/

> > +pub unsafe trait OwnableMut: Ownable {}
> 
> I don't like the name, but at the same time I also have no good
> suggestion :( I'll think some more about it.

There was already a bit of discussion about it. I had my own implementation of this
where I used the names `UniqueRefCounted` and `UniqueRef`, but after discovering
this version from Asahi Lina, I took it as it was, keeping the name.

No one else came up with different suggestions so far, so maybe we should just leave it
at `Owned`/`Ownable`?

Best,

Oliver
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Benno Lossin 7 months, 3 weeks ago
On Wed Jun 18, 2025 at 11:34 AM CEST, Oliver Mangold wrote:
> On 250514 1132, Benno Lossin wrote:
>> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
>> 
>> > +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
>> > +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
>> > +///   while Rust owns it.
>> 
>> I feel like this requirement is better put on the `Owned::from_raw`
>> function.
>
> Thinking about it some more, the problem I see here is that if the type
> implements `OwnableMut` this requirement changes from "never mutate" to
> "never access at all".
>
> The safety requirements between `Ownable`, `OwnableMut`, `RefCounted`,
> `OwnableRefCounted` and `AlwaysRefCounted` are interacting, but I agree
> that, when looking at it a certain way, `Owned::from_raw()` is the place
> where one would expect these to be. I'm not sure anymore what is best here
> :/

I still think `Owned::from_raw` is the correct place to put this.

>
>> > +pub unsafe trait OwnableMut: Ownable {}
>> 
>> I don't like the name, but at the same time I also have no good
>> suggestion :( I'll think some more about it.
>
> There was already a bit of discussion about it. I had my own implementation of this
> where I used the names `UniqueRefCounted` and `UniqueRef`, but after discovering
> this version from Asahi Lina, I took it as it was, keeping the name.
>
> No one else came up with different suggestions so far, so maybe we should just leave it
> at `Owned`/`Ownable`?

I'm just hung up on the `Mut` part... Haven't come up with a good
replacement yet.

---
Cheers,
Benno
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Andreas Hindborg 7 months, 3 weeks ago
"Benno Lossin" <lossin@kernel.org> writes:

> On Wed Jun 18, 2025 at 11:34 AM CEST, Oliver Mangold wrote:
>> On 250514 1132, Benno Lossin wrote:
>>> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
>>>
>>> > +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
>>> > +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
>>> > +///   while Rust owns it.
>>>
>>> I feel like this requirement is better put on the `Owned::from_raw`
>>> function.
>>
>> Thinking about it some more, the problem I see here is that if the type
>> implements `OwnableMut` this requirement changes from "never mutate" to
>> "never access at all".
>>
>> The safety requirements between `Ownable`, `OwnableMut`, `RefCounted`,
>> `OwnableRefCounted` and `AlwaysRefCounted` are interacting, but I agree
>> that, when looking at it a certain way, `Owned::from_raw()` is the place
>> where one would expect these to be. I'm not sure anymore what is best here
>> :/
>
> I still think `Owned::from_raw` is the correct place to put this.
>
>>
>>> > +pub unsafe trait OwnableMut: Ownable {}
>>>
>>> I don't like the name, but at the same time I also have no good
>>> suggestion :( I'll think some more about it.
>>
>> There was already a bit of discussion about it. I had my own implementation of this
>> where I used the names `UniqueRefCounted` and `UniqueRef`, but after discovering
>> this version from Asahi Lina, I took it as it was, keeping the name.
>>
>> No one else came up with different suggestions so far, so maybe we should just leave it
>> at `Owned`/`Ownable`?
>
> I'm just hung up on the `Mut` part... Haven't come up with a good
> replacement yet.

What do you dislike about the xxxxMut pattern?


Best regards,
Andreas Hindborg
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Benno Lossin 7 months, 3 weeks ago
On Thu Jun 19, 2025 at 11:33 AM CEST, Andreas Hindborg wrote:
> "Benno Lossin" <lossin@kernel.org> writes:
>> On Wed Jun 18, 2025 at 11:34 AM CEST, Oliver Mangold wrote:
>>> On 250514 1132, Benno Lossin wrote:
>>>> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
>>>> > +pub unsafe trait OwnableMut: Ownable {}
>>>>
>>>> I don't like the name, but at the same time I also have no good
>>>> suggestion :( I'll think some more about it.
>>>
>>> There was already a bit of discussion about it. I had my own implementation of this
>>> where I used the names `UniqueRefCounted` and `UniqueRef`, but after discovering
>>> this version from Asahi Lina, I took it as it was, keeping the name.
>>>
>>> No one else came up with different suggestions so far, so maybe we should just leave it
>>> at `Owned`/`Ownable`?
>>
>> I'm just hung up on the `Mut` part... Haven't come up with a good
>> replacement yet.
>
> What do you dislike about the xxxxMut pattern?

Uh, I have re-read the docs & don't remember what originally I didn't
like about the name, so let's keep it :)

---
Cheers,
Benno
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Oliver Mangold 7 months, 3 weeks ago
On 250514 1132, Benno Lossin wrote:
> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
> > +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
> > +///
> > +/// It allows such types to define their own custom destructor function to be called when
> > +/// a Rust-owned reference is dropped.
> > +///
> > +/// This is usually implemented by wrappers to existing structures on the C side of the code.
> 
> The docs should mention `AlwaysRefCounted` and when to use it instead of
> this trait. We should probably also backlink from `AlwaysRefCounted` to
> `Ownable`.

Will do.

> > +///
> > +/// # Safety
> > +///
> > +/// Implementers must ensure that:
> > +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> > +///   until the [`release()`](Ownable::release) trait method is called).
> 
> I don't immediately understand what this means. How about "Any value of
> type `Self` needs to be stored as [`Owned<Self>`]."?

Let me think. The safety requirements here talk about safety of
implementing the trait.  But if you have a `Self` which is not wrapped, you
still cannot create an `Owned<Self>` in safe code. It's different from an
`AlwaysRefCounted`, where an `ARef<Self>` can be created from a `&Self`.

> And then ask in
> `Owned::from_raw` for a pointer that is valid indefinitely (or at least
> until `release` is called).

So, hmm, I think one could even move this safety requirement to `Owned::from_raw()`.

> > +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> > +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> > +///   while Rust owns it.
> 
> I feel like this requirement is better put on the `Owned::from_raw`
> function.

Together with the above, this would leave to safety requirements for `Ownable.
Make `Ownable` a safe trait, then? Instead of safety requirements just add an invariant:

    # Invariant
    
    An `Owned<Self>` represents a unique reference to a `Self`, thus holding
    an `Owned<Self>` or `&mut Owned<Self>` allows one to assume that the object
    is not accessed concurrently from elsewhere.

Not sure what is best. Would that make sense?

> > +pub unsafe trait Ownable {
> > +    /// Releases the object (frees it or returns it to foreign ownership).
> > +    ///
> > +    /// # Safety
> > +    ///
> > +    /// Callers must ensure that the object is no longer referenced after this call.
> > +    unsafe fn release(this: NonNull<Self>);
> > +}
> > +
> > +/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
> > +/// may be dereferenced into a `&mut T`.
> 
> The "A subtrait of Ownable that asserts" sounds a bit clumsy to me, how
> about "Type where [`Owned<Self>`] derefs to `&mut Self`."?

That's okay with me.

> > +///
> > +/// # Safety
> > +///
> > +/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
> > +/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).
> 
> I don't like that we put this requirement here, since it's actually
> something that should be asserted by `Owned::from_raw`.
> The reason for that is that anyone can call `Owned::from_raw` with a
> pointer pointing to `Self` and there is no safety requirement on that
> function that ensures the correctness of the `DerefMut` impl.
> 
> > +pub unsafe trait OwnableMut: Ownable {}
> 
> I don't like the name, but at the same time I also have no good
> suggestion :( I'll think some more about it.
> 
> ---
> Cheers,
> Benno

Best regards,

Oliver
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Benno Lossin 7 months, 3 weeks ago
On Tue Jun 17, 2025 at 11:58 AM CEST, Oliver Mangold wrote:
> On 250514 1132, Benno Lossin wrote:
>> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
>> > +///
>> > +/// # Safety
>> > +///
>> > +/// Implementers must ensure that:
>> > +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
>> > +///   until the [`release()`](Ownable::release) trait method is called).
>> 
>> I don't immediately understand what this means. How about "Any value of
>> type `Self` needs to be stored as [`Owned<Self>`]."?
>
> Let me think. The safety requirements here talk about safety of
> implementing the trait.  But if you have a `Self` which is not wrapped, you
> still cannot create an `Owned<Self>` in safe code. It's different from an
> `AlwaysRefCounted`, where an `ARef<Self>` can be created from a `&Self`.

That might be true, but AFAIK this trait is designed to be used for
stuff that has a `create_foo` and `destroy_foo` function in C returning
and taking a raw pointer to `foo` respectively. So creating it on the
stack doesn't make sense.

If we do want to make this trait more general, then we can do so, but
this is my current understanding.

>> And then ask in
>> `Owned::from_raw` for a pointer that is valid indefinitely (or at least
>> until `release` is called).
>
> So, hmm, I think one could even move this safety requirement to `Owned::from_raw()`.
>
>> > +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
>> > +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
>> > +///   while Rust owns it.
>> 
>> I feel like this requirement is better put on the `Owned::from_raw`
>> function.
>
> Together with the above, this would leave to safety requirements for `Ownable.
> Make `Ownable` a safe trait, then? Instead of safety requirements just add an invariant:
>
>     # Invariant
>     
>     An `Owned<Self>` represents a unique reference to a `Self`, thus holding
>     an `Owned<Self>` or `&mut Owned<Self>` allows one to assume that the object
>     is not accessed concurrently from elsewhere.
>
> Not sure what is best. Would that make sense?

Making it safe makes sense, when we can move all requirements to
`Owned::from_raw`. I don't think the invariants section makes sense, how
would the trait have any influence in that when `Owned::from_raw`
already guarantees it?

---
Cheers,
Benno
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Oliver Mangold 7 months, 3 weeks ago
On 250618 2322, Benno Lossin wrote:
> On Tue Jun 17, 2025 at 11:58 AM CEST, Oliver Mangold wrote:
> > On 250514 1132, Benno Lossin wrote:
> >> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
> >> > +///
> >> > +/// # Safety
> >> > +///
> >> > +/// Implementers must ensure that:
> >> > +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> >> > +///   until the [`release()`](Ownable::release) trait method is called).
> >>
> >> I don't immediately understand what this means. How about "Any value of
> >> type `Self` needs to be stored as [`Owned<Self>`]."?
> >
> > Let me think. The safety requirements here talk about safety of
> > implementing the trait.  But if you have a `Self` which is not wrapped, you
> > still cannot create an `Owned<Self>` in safe code. It's different from an
> > `AlwaysRefCounted`, where an `ARef<Self>` can be created from a `&Self`.
> 
> That might be true, but AFAIK this trait is designed to be used for
> stuff that has a `create_foo` and `destroy_foo` function in C returning
> and taking a raw pointer to `foo` respectively. So creating it on the
> stack doesn't make sense.

I didn't mean creating one on the stack, but keeping it in a raw pointer or
`NonNull<T>`, not bothering to wrap in in an `Owned<T>`. But doesn't
matter. In any case in v11 (which predates your answer), I moved this
requirement to `Owned::from_raw()`, as, you asked below, which should be
okay as that function is the only way to create an `Owned<T>`. But I can
add the "needs to be stored as `Owned<Self>`" requirement, if you think it
is important.


> If we do want to make this trait more general, then we can do so, but
> this is my current understanding.
> 
> >> And then ask in
> >> `Owned::from_raw` for a pointer that is valid indefinitely (or at least
> >> until `release` is called).
> >
> > So, hmm, I think one could even move this safety requirement to `Owned::from_raw()`.
> >
> >> > +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> >> > +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> >> > +///   while Rust owns it.
> >>
> >> I feel like this requirement is better put on the `Owned::from_raw`
> >> function.
> >
> > Together with the above, this would leave to safety requirements for `Ownable.
> > Make `Ownable` a safe trait, then? Instead of safety requirements just add an invariant:
> >
> >     # Invariant
> >
> >     An `Owned<Self>` represents a unique reference to a `Self`, thus holding
> >     an `Owned<Self>` or `&mut Owned<Self>` allows one to assume that the object
> >     is not accessed concurrently from elsewhere.
> >
> > Not sure what is best. Would that make sense?
> 
> Making it safe makes sense, when we can move all requirements to
> `Owned::from_raw`. I don't think the invariants section makes sense, how
> would the trait have any influence in that when `Owned::from_raw`
> already guarantees it?

I think you are right on that. Let's not do that.

Best,

Oliver
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Benno Lossin 7 months, 3 weeks ago
On Fri Jun 20, 2025 at 9:01 AM CEST, Oliver Mangold wrote:
> On 250618 2322, Benno Lossin wrote:
>> On Tue Jun 17, 2025 at 11:58 AM CEST, Oliver Mangold wrote:
>> > On 250514 1132, Benno Lossin wrote:
>> >> On Fri May 2, 2025 at 11:02 AM CEST, Oliver Mangold wrote:
>> >> > +///
>> >> > +/// # Safety
>> >> > +///
>> >> > +/// Implementers must ensure that:
>> >> > +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
>> >> > +///   until the [`release()`](Ownable::release) trait method is called).
>> >>
>> >> I don't immediately understand what this means. How about "Any value of
>> >> type `Self` needs to be stored as [`Owned<Self>`]."?
>> >
>> > Let me think. The safety requirements here talk about safety of
>> > implementing the trait.  But if you have a `Self` which is not wrapped, you
>> > still cannot create an `Owned<Self>` in safe code. It's different from an
>> > `AlwaysRefCounted`, where an `ARef<Self>` can be created from a `&Self`.
>> 
>> That might be true, but AFAIK this trait is designed to be used for
>> stuff that has a `create_foo` and `destroy_foo` function in C returning
>> and taking a raw pointer to `foo` respectively. So creating it on the
>> stack doesn't make sense.
>
> I didn't mean creating one on the stack, but keeping it in a raw pointer or
> `NonNull<T>`, not bothering to wrap in in an `Owned<T>`. But doesn't
> matter. In any case in v11 (which predates your answer), I moved this
> requirement to `Owned::from_raw()`, as, you asked below, which should be
> okay as that function is the only way to create an `Owned<T>`. But I can
> add the "needs to be stored as `Owned<Self>`" requirement, if you think it
> is important.

I'm not so sure, it depends on what we want `Owned<T>` to be. When I
take a look at v11, I might be able to figure it out.

---
Cheers,
Benno
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Andreas Hindborg 9 months ago
"Oliver Mangold" <oliver.mangold@pm.me> writes:

> From: Asahi Lina <lina@asahilina.net>
>
> By analogy to AlwaysRefCounted and ARef, an Ownable type is a (typically
> C FFI) type that *may* be owned by Rust, but need not be. Unlike
> AlwaysRefCounted, this mechanism expects the reference to be unique
> within Rust, and does not allow cloning.
>
> Conceptually, this is similar to a KBox<T>, except that it delegates
> resource management to the T instead of using a generic allocator.
>
> Link: https://lore.kernel.org/all/20250202-rust-page-v1-1-e3170d7fe55e@asahilina.net/
> Signed-off-by: Asahi Lina <lina@asahilina.net>
> [ om:
>   - split code into separate file and `pub use` it from types.rs
>   - make from_raw() and into_raw() public
>   - fixes to documentation
> ]
> Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
> ---
>  rust/kernel/types.rs         |   3 ++
>  rust/kernel/types/ownable.rs | 117 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)
>
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index 9d0471afc9648f2973235488b441eb109069adb1..5d8a99dcba4bf733107635bf3f0c15840ec33e4c 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -11,6 +11,9 @@
>  };
>  use pin_init::{PinInit, Zeroable};
>
> +pub mod ownable;
> +pub use ownable::{Ownable, OwnableMut, Owned};
> +
>  /// Used to transfer ownership to and from foreign (non-Rust) languages.
>  ///
>  /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
> diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
> new file mode 100644
> index 0000000000000000000000000000000000000000..52e7a69019f1e2bbbe3cf715651b67a5a5c7c13d
> --- /dev/null
> +++ b/rust/kernel/types/ownable.rs
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Owned reference types.
> +
> +use core::{
> +    marker::PhantomData,
> +    mem::ManuallyDrop,
> +    ops::{Deref, DerefMut},
> +    ptr::NonNull,
> +};
> +
> +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
> +///
> +/// It allows such types to define their own custom destructor function to be called when
> +/// a Rust-owned reference is dropped.
> +///
> +/// This is usually implemented by wrappers to existing structures on the C side of the code.
> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that:
> +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> +///   until the [`release()`](Ownable::release) trait method is called).
> +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> +///   while Rust owns it.
> +pub unsafe trait Ownable {
> +    /// Releases the object (frees it or returns it to foreign ownership).
> +    ///
> +    /// # Safety
> +    ///
> +    /// Callers must ensure that the object is no longer referenced after this call.
> +    unsafe fn release(this: NonNull<Self>);

We should probably add as a safety requirement that `this` points to a
valid `Self`.


Best regards,
Andreas Hindborg
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Alice Ryhl 9 months, 1 week ago
On Fri, May 02, 2025 at 09:02:29AM +0000, Oliver Mangold wrote:
> From: Asahi Lina <lina@asahilina.net>
> 
> By analogy to AlwaysRefCounted and ARef, an Ownable type is a (typically
> C FFI) type that *may* be owned by Rust, but need not be. Unlike
> AlwaysRefCounted, this mechanism expects the reference to be unique
> within Rust, and does not allow cloning.
> 
> Conceptually, this is similar to a KBox<T>, except that it delegates
> resource management to the T instead of using a generic allocator.
> 
> Link: https://lore.kernel.org/all/20250202-rust-page-v1-1-e3170d7fe55e@asahilina.net/
> Signed-off-by: Asahi Lina <lina@asahilina.net>
> [ om:
>   - split code into separate file and `pub use` it from types.rs
>   - make from_raw() and into_raw() public
>   - fixes to documentation
> ]
> Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
> ---
>  rust/kernel/types.rs         |   3 ++
>  rust/kernel/types/ownable.rs | 117 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)
> 
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index 9d0471afc9648f2973235488b441eb109069adb1..5d8a99dcba4bf733107635bf3f0c15840ec33e4c 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -11,6 +11,9 @@
>  };
>  use pin_init::{PinInit, Zeroable};
>  
> +pub mod ownable;
> +pub use ownable::{Ownable, OwnableMut, Owned};
> +
>  /// Used to transfer ownership to and from foreign (non-Rust) languages.
>  ///
>  /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
> diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
> new file mode 100644
> index 0000000000000000000000000000000000000000..52e7a69019f1e2bbbe3cf715651b67a5a5c7c13d
> --- /dev/null
> +++ b/rust/kernel/types/ownable.rs
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Owned reference types.
> +
> +use core::{
> +    marker::PhantomData,
> +    mem::ManuallyDrop,
> +    ops::{Deref, DerefMut},
> +    ptr::NonNull,
> +};
> +
> +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
> +///
> +/// It allows such types to define their own custom destructor function to be called when
> +/// a Rust-owned reference is dropped.
> +///
> +/// This is usually implemented by wrappers to existing structures on the C side of the code.
> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that:
> +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> +///   until the [`release()`](Ownable::release) trait method is called).
> +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> +///   while Rust owns it.

This seems too strong? Or does the exception mean to say that this does
not apply to anything containing `Opaque`? By far most structs using
this will use Opaque, so maybe directly mention Opaque instead?

That C code follows the usual aliasing rules. That is, unless the value
is wrapped in `Opaque` (or `UnsafeCell`), then the value must not be
modified in any way while Rust owns it, unless that modification happens
inside a `&mut T` method on the value.

> +pub unsafe trait Ownable {
> +    /// Releases the object (frees it or returns it to foreign ownership).
> +    ///
> +    /// # Safety
> +    ///
> +    /// Callers must ensure that the object is no longer referenced after this call.
> +    unsafe fn release(this: NonNull<Self>);
> +}
> +
> +/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
> +/// may be dereferenced into a `&mut T`.
> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
> +/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).
> +pub unsafe trait OwnableMut: Ownable {}
> +
> +/// An owned reference to an ownable kernel object.
> +///
> +/// The object is automatically freed or released when an instance of [`Owned`] is
> +/// dropped.
> +///
> +/// # Invariants
> +///
> +/// The pointer stored in `ptr` is valid for the lifetime of the [`Owned`] instance.

This should probably talk about ownership.

> +pub struct Owned<T: Ownable> {
> +    ptr: NonNull<T>,
> +    _p: PhantomData<T>,
> +}

Alice
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Andreas Hindborg 9 months, 1 week ago
"Alice Ryhl" <aliceryhl@google.com> writes:

> On Fri, May 02, 2025 at 09:02:29AM +0000, Oliver Mangold wrote:
>> From: Asahi Lina <lina@asahilina.net>
>>
>> By analogy to AlwaysRefCounted and ARef, an Ownable type is a (typically
>> C FFI) type that *may* be owned by Rust, but need not be. Unlike
>> AlwaysRefCounted, this mechanism expects the reference to be unique
>> within Rust, and does not allow cloning.
>>
>> Conceptually, this is similar to a KBox<T>, except that it delegates
>> resource management to the T instead of using a generic allocator.
>>
>> Link: https://lore.kernel.org/all/20250202-rust-page-v1-1-e3170d7fe55e@asahilina.net/
>> Signed-off-by: Asahi Lina <lina@asahilina.net>
>> [ om:
>>   - split code into separate file and `pub use` it from types.rs
>>   - make from_raw() and into_raw() public
>>   - fixes to documentation
>> ]
>> Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
>> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
>> ---
>>  rust/kernel/types.rs         |   3 ++
>>  rust/kernel/types/ownable.rs | 117 +++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 120 insertions(+)
>>
>> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
>> index 9d0471afc9648f2973235488b441eb109069adb1..5d8a99dcba4bf733107635bf3f0c15840ec33e4c 100644
>> --- a/rust/kernel/types.rs
>> +++ b/rust/kernel/types.rs
>> @@ -11,6 +11,9 @@
>>  };
>>  use pin_init::{PinInit, Zeroable};
>>
>> +pub mod ownable;
>> +pub use ownable::{Ownable, OwnableMut, Owned};
>> +
>>  /// Used to transfer ownership to and from foreign (non-Rust) languages.
>>  ///
>>  /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
>> diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..52e7a69019f1e2bbbe3cf715651b67a5a5c7c13d
>> --- /dev/null
>> +++ b/rust/kernel/types/ownable.rs
>> @@ -0,0 +1,117 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +//! Owned reference types.
>> +
>> +use core::{
>> +    marker::PhantomData,
>> +    mem::ManuallyDrop,
>> +    ops::{Deref, DerefMut},
>> +    ptr::NonNull,
>> +};
>> +
>> +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
>> +///
>> +/// It allows such types to define their own custom destructor function to be called when
>> +/// a Rust-owned reference is dropped.
>> +///
>> +/// This is usually implemented by wrappers to existing structures on the C side of the code.
>> +///
>> +/// # Safety
>> +///
>> +/// Implementers must ensure that:
>> +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
>> +///   until the [`release()`](Ownable::release) trait method is called).
>> +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
>> +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
>> +///   while Rust owns it.
>
> This seems too strong? Or does the exception mean to say that this does
> not apply to anything containing `Opaque`? By far most structs using
> this will use Opaque, so maybe directly mention Opaque instead?

`Opaque` is covered by "(excluding internal mutability that follows the usual rules)".

>
> That C code follows the usual aliasing rules. That is, unless the value
> is wrapped in `Opaque` (or `UnsafeCell`), then the value must not be
> modified in any way while Rust owns it, unless that modification happens
> inside a `&mut T` method on the value.
>
>> +pub unsafe trait Ownable {
>> +    /// Releases the object (frees it or returns it to foreign ownership).
>> +    ///
>> +    /// # Safety
>> +    ///
>> +    /// Callers must ensure that the object is no longer referenced after this call.
>> +    unsafe fn release(this: NonNull<Self>);
>> +}
>> +
>> +/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
>> +/// may be dereferenced into a `&mut T`.
>> +///
>> +/// # Safety
>> +///
>> +/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
>> +/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).
>> +pub unsafe trait OwnableMut: Ownable {}
>> +
>> +/// An owned reference to an ownable kernel object.
>> +///
>> +/// The object is automatically freed or released when an instance of [`Owned`] is
>> +/// dropped.
>> +///
>> +/// # Invariants
>> +///
>> +/// The pointer stored in `ptr` is valid for the lifetime of the [`Owned`] instance.
>
> This should probably talk about ownership.

How about

  The pointee of `ptr` can be considered owned by the [`Owned`] instance.


Best regards,
Andreas Hindborg
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Alice Ryhl 9 months, 1 week ago
On Tue, May 06, 2025 at 01:20:04PM +0200, Andreas Hindborg wrote:
> "Alice Ryhl" <aliceryhl@google.com> writes:
> 
> > On Fri, May 02, 2025 at 09:02:29AM +0000, Oliver Mangold wrote:
> >> From: Asahi Lina <lina@asahilina.net>
> >>
> >> By analogy to AlwaysRefCounted and ARef, an Ownable type is a (typically
> >> C FFI) type that *may* be owned by Rust, but need not be. Unlike
> >> AlwaysRefCounted, this mechanism expects the reference to be unique
> >> within Rust, and does not allow cloning.
> >>
> >> Conceptually, this is similar to a KBox<T>, except that it delegates
> >> resource management to the T instead of using a generic allocator.
> >>
> >> Link: https://lore.kernel.org/all/20250202-rust-page-v1-1-e3170d7fe55e@asahilina.net/
> >> Signed-off-by: Asahi Lina <lina@asahilina.net>
> >> [ om:
> >>   - split code into separate file and `pub use` it from types.rs
> >>   - make from_raw() and into_raw() public
> >>   - fixes to documentation
> >> ]
> >> Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
> >> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
> >> ---
> >>  rust/kernel/types.rs         |   3 ++
> >>  rust/kernel/types/ownable.rs | 117 +++++++++++++++++++++++++++++++++++++++++++
> >>  2 files changed, 120 insertions(+)
> >>
> >> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> >> index 9d0471afc9648f2973235488b441eb109069adb1..5d8a99dcba4bf733107635bf3f0c15840ec33e4c 100644
> >> --- a/rust/kernel/types.rs
> >> +++ b/rust/kernel/types.rs
> >> @@ -11,6 +11,9 @@
> >>  };
> >>  use pin_init::{PinInit, Zeroable};
> >>
> >> +pub mod ownable;
> >> +pub use ownable::{Ownable, OwnableMut, Owned};
> >> +
> >>  /// Used to transfer ownership to and from foreign (non-Rust) languages.
> >>  ///
> >>  /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
> >> diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
> >> new file mode 100644
> >> index 0000000000000000000000000000000000000000..52e7a69019f1e2bbbe3cf715651b67a5a5c7c13d
> >> --- /dev/null
> >> +++ b/rust/kernel/types/ownable.rs
> >> @@ -0,0 +1,117 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +
> >> +//! Owned reference types.
> >> +
> >> +use core::{
> >> +    marker::PhantomData,
> >> +    mem::ManuallyDrop,
> >> +    ops::{Deref, DerefMut},
> >> +    ptr::NonNull,
> >> +};
> >> +
> >> +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
> >> +///
> >> +/// It allows such types to define their own custom destructor function to be called when
> >> +/// a Rust-owned reference is dropped.
> >> +///
> >> +/// This is usually implemented by wrappers to existing structures on the C side of the code.
> >> +///
> >> +/// # Safety
> >> +///
> >> +/// Implementers must ensure that:
> >> +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> >> +///   until the [`release()`](Ownable::release) trait method is called).
> >> +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> >> +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> >> +///   while Rust owns it.
> >
> > This seems too strong? Or does the exception mean to say that this does
> > not apply to anything containing `Opaque`? By far most structs using
> > this will use Opaque, so maybe directly mention Opaque instead?
> 
> `Opaque` is covered by "(excluding internal mutability that follows the usual rules)".

I guess. But I think it would still be good to rephrase to mention
Opaque for ease of understanding.

> > That C code follows the usual aliasing rules. That is, unless the value
> > is wrapped in `Opaque` (or `UnsafeCell`), then the value must not be
> > modified in any way while Rust owns it, unless that modification happens
> > inside a `&mut T` method on the value.
> >
> >> +pub unsafe trait Ownable {
> >> +    /// Releases the object (frees it or returns it to foreign ownership).
> >> +    ///
> >> +    /// # Safety
> >> +    ///
> >> +    /// Callers must ensure that the object is no longer referenced after this call.
> >> +    unsafe fn release(this: NonNull<Self>);
> >> +}
> >> +
> >> +/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
> >> +/// may be dereferenced into a `&mut T`.
> >> +///
> >> +/// # Safety
> >> +///
> >> +/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
> >> +/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).
> >> +pub unsafe trait OwnableMut: Ownable {}
> >> +
> >> +/// An owned reference to an ownable kernel object.
> >> +///
> >> +/// The object is automatically freed or released when an instance of [`Owned`] is
> >> +/// dropped.
> >> +///
> >> +/// # Invariants
> >> +///
> >> +/// The pointer stored in `ptr` is valid for the lifetime of the [`Owned`] instance.
> >
> > This should probably talk about ownership.
> 
> How about
> 
>   The pointee of `ptr` can be considered owned by the [`Owned`] instance.

Sure.

Alice
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Andreas Hindborg 9 months, 1 week ago
"Oliver Mangold" <oliver.mangold@pm.me> writes:

> From: Asahi Lina <lina@asahilina.net>
>
> By analogy to AlwaysRefCounted and ARef, an Ownable type is a (typically
> C FFI) type that *may* be owned by Rust, but need not be. Unlike
> AlwaysRefCounted, this mechanism expects the reference to be unique
> within Rust, and does not allow cloning.
>
> Conceptually, this is similar to a KBox<T>, except that it delegates
> resource management to the T instead of using a generic allocator.
>
> Link: https://lore.kernel.org/all/20250202-rust-page-v1-1-e3170d7fe55e@asahilina.net/
> Signed-off-by: Asahi Lina <lina@asahilina.net>
> [ om:
>   - split code into separate file and `pub use` it from types.rs
>   - make from_raw() and into_raw() public
>   - fixes to documentation
> ]
> Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
> ---
>  rust/kernel/types.rs         |   3 ++
>  rust/kernel/types/ownable.rs | 117 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)
>
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index 9d0471afc9648f2973235488b441eb109069adb1..5d8a99dcba4bf733107635bf3f0c15840ec33e4c 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -11,6 +11,9 @@
>  };
>  use pin_init::{PinInit, Zeroable};
>
> +pub mod ownable;
> +pub use ownable::{Ownable, OwnableMut, Owned};
> +
>  /// Used to transfer ownership to and from foreign (non-Rust) languages.
>  ///
>  /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
> diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
> new file mode 100644
> index 0000000000000000000000000000000000000000..52e7a69019f1e2bbbe3cf715651b67a5a5c7c13d
> --- /dev/null
> +++ b/rust/kernel/types/ownable.rs
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Owned reference types.
> +
> +use core::{
> +    marker::PhantomData,
> +    mem::ManuallyDrop,
> +    ops::{Deref, DerefMut},
> +    ptr::NonNull,
> +};
> +
> +/// Types that may be owned by Rust code or borrowed, but have a lifetime managed by C code.
> +///
> +/// It allows such types to define their own custom destructor function to be called when
> +/// a Rust-owned reference is dropped.
> +///
> +/// This is usually implemented by wrappers to existing structures on the C side of the code.
> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that:
> +/// - Any objects owned by Rust as [`Owned<T>`] stay alive while that owned reference exists (i.e.
> +///   until the [`release()`](Ownable::release) trait method is called).
> +/// - That the C code follows the usual mutable reference requirements. That is, the kernel will
> +///   never mutate the [`Ownable`] (excluding internal mutability that follows the usual rules)
> +///   while Rust owns it.
> +pub unsafe trait Ownable {
> +    /// Releases the object (frees it or returns it to foreign ownership).
> +    ///
> +    /// # Safety
> +    ///
> +    /// Callers must ensure that the object is no longer referenced after this call.
> +    unsafe fn release(this: NonNull<Self>);
> +}
> +
> +/// A subtrait of Ownable that asserts that an [`Owned<T>`] or `&mut Owned<T>` Rust reference
> +/// may be dereferenced into a `&mut T`.
> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that access to a `&mut T` is safe, implying that it is okay to call
> +/// [`core::mem::swap`] on the `Ownable`. This excludes pinned types (meaning: most kernel types).
> +pub unsafe trait OwnableMut: Ownable {}
> +
> +/// An owned reference to an ownable kernel object.
> +///
> +/// The object is automatically freed or released when an instance of [`Owned`] is
> +/// dropped.
> +///
> +/// # Invariants
> +///
> +/// The pointer stored in `ptr` is valid for the lifetime of the [`Owned`] instance.
> +pub struct Owned<T: Ownable> {
> +    ptr: NonNull<T>,
> +    _p: PhantomData<T>,
> +}
> +
> +// SAFETY: It is safe to send `Owned<T>` to another thread when the underlying `T` is `Send` because
> +// it effectively means sending a `&mut T` (which is safe because `T` is `Send`).
> +unsafe impl<T: Ownable + Send> Send for Owned<T> {}
> +
> +// SAFETY: It is safe to send `&Owned<T>` to another thread when the underlying `T` is `Sync`
> +// because it effectively means sharing `&T` (which is safe because `T` is `Sync`).
> +unsafe impl<T: Ownable + Sync> Sync for Owned<T> {}
> +
> +impl<T: Ownable> Owned<T> {
> +    /// Creates a new instance of [`Owned`].
> +    ///
> +    /// It takes over ownership of the underlying object.
> +    ///
> +    /// # Safety
> +    ///
> +    /// Callers must ensure that the underlying object is acquired and can be considered owned by
> +    /// Rust.


This part "the underlying object is acquired" is unclear to me. How about:

  Callers must ensure that *ownership of* the underlying object has been
  acquired. That is, the object can be considered owned by the caller.


Best regards,
Andreas Hindborg
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Oliver Mangold 7 months, 3 weeks ago
On 250502 1157, Andreas Hindborg wrote:
> > +
> > +impl<T: Ownable> Owned<T> {
> > +    /// Creates a new instance of [`Owned`].
> > +    ///
> > +    /// It takes over ownership of the underlying object.
> > +    ///
> > +    /// # Safety
> > +    ///
> > +    /// Callers must ensure that the underlying object is acquired and can be considered owned by
> > +    /// Rust.
> 
> 
> This part "the underlying object is acquired" is unclear to me. How about:
> 
>   Callers must ensure that *ownership of* the underlying object has been
>   acquired. That is, the object can be considered owned by the caller.
> 
> 

Yes, made me think about the phrasing, too. But the main point is, that the
object must be considered to be owned by the `Owned<T>` after the function
call, no?

So maybe:

   Callers must ensure that ownership of the underlying object can be
   transfered to the `Owned<T>` and must consider it to be transfered
   after the function call. This usually implies that the object
   most not be accessed through `ptr` anymore.
Re: [PATCH v10 1/5] rust: types: Add Ownable/Owned types
Posted by Andreas Hindborg 7 months, 3 weeks ago
"Oliver Mangold" <oliver.mangold@pm.me> writes:

> On 250502 1157, Andreas Hindborg wrote:
>> > +
>> > +impl<T: Ownable> Owned<T> {
>> > +    /// Creates a new instance of [`Owned`].
>> > +    ///
>> > +    /// It takes over ownership of the underlying object.
>> > +    ///
>> > +    /// # Safety
>> > +    ///
>> > +    /// Callers must ensure that the underlying object is acquired and can be considered owned by
>> > +    /// Rust.
>>
>>
>> This part "the underlying object is acquired" is unclear to me. How about:
>>
>>   Callers must ensure that *ownership of* the underlying object has been
>>   acquired. That is, the object can be considered owned by the caller.
>>
>>
>
> Yes, made me think about the phrasing, too. But the main point is, that the
> object must be considered to be owned by the `Owned<T>` after the function
> call, no?
>
> So maybe:
>
>    Callers must ensure that ownership of the underlying object can be
>    transfered to the `Owned<T>` and must consider it to be transfered
>    after the function call. This usually implies that the object
>    most not be accessed through `ptr` anymore.

Sounds good to me 👍


Best regards,
Andreas Hindborg