From: Oliver Mangold <oliver.mangold@pm.me>
To: Benno Lossin <lossin@kernel.org>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Asahi Lina" <lina+kernel@asahilina.net>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v11 4/4] rust: Add `OwnableRefCounted`
Date: Mon, 07 Jul 2025 08:07:40 +0000 [thread overview]
Message-ID: <aGuAR7JCrlmzQrx4@mango> (raw)
In-Reply-To: <DB1LPFAX66WG.1QL5JDCWI7RN4@kernel.org>
On 250702 1524, Benno Lossin wrote:
> On Wed Jun 18, 2025 at 2:27 PM CEST, Oliver Mangold wrote:
> > diff --git a/rust/kernel/types/ownable.rs b/rust/kernel/types/ownable.rs
> > index 80cd990f6601767aa5a742a6c0997f4f67d06453..b5626dead6bb25ea76a0ae577db1b130308d98b1 100644
> > --- a/rust/kernel/types/ownable.rs
> > +++ b/rust/kernel/types/ownable.rs
> > @@ -2,6 +2,7 @@
> >
> > //! Owned reference types.
> >
> > +use crate::types::{ARef, RefCounted};
> > use core::{
> > marker::PhantomData,
> > mem::ManuallyDrop,
> > @@ -18,8 +19,9 @@
> > ///
> > /// Note: Implementing this trait allows types to be wrapped in an [`Owned<Self>`]. This does not
> > /// provide reference counting but represents a unique, owned reference. If reference counting is
> > -/// required [`RefCounted`](crate::types::RefCounted) should be implemented which allows types to be
> > -/// wrapped in an [`ARef<Self>`](crate::types::ARef).
> > +/// required [`RefCounted`] should be implemented which allows types to be wrapped in an
> > +/// [`ARef<Self>`]. Implementing the trait [`OwnableRefCounted`] allows to convert between unique
> > +/// and shared references (i.e. [`Owned<Self>`] and [`ARef<Self>`]).
>
> This change should probably be in the earlier patch.
Ah, yes. Must have happened while splitting the patches.
> > ///
> > /// # Safety
> > ///
> > @@ -132,3 +134,124 @@ fn drop(&mut self) {
> > unsafe { T::release(self.ptr) };
> > }
> > }
> > +
> > +/// A trait for objects that can be wrapped in either one of the reference types [`Owned`] and
> > +/// [`ARef`].
> > +///
> > +/// # Safety
> > +///
> > +/// Implementers must ensure that:
> > +///
> > +/// - [`try_from_shared()`](OwnableRefCounted::into_shared) only returns an [`Owned<Self>`] if
> > +/// exactly one [`ARef<Self>`] exists.
>
> This shouldn't be required?
Ehm, why not? `Owned<T>` is supposed to be unique.
> > +/// - [`into_shared()`](OwnableRefCounted::into_shared) set the reference count to the value which
> > +/// the returned [`ARef<Self>`] expects for an object with a single reference in existence. This
> > +/// implies that if [`into_shared()`](OwnableRefCounted::into_shared) is left on the default
> > +/// implementation, which just rewraps the underlying object, the reference count needs not to be
> > +/// modified when converting an [`Owned<Self>`] to an [`ARef<Self>`].
>
> This also seems pretty weird...
>
> I feel like `OwnableRefCounted` is essentially just a compatibility
> condition between `Ownable` and `RefCounted`. It ensures that the
> ownership declared in `Ownable` corresponds to exactly one refcount
> declared in `RefCounted`.
>
> That being said, I think a `RefCounted` *always* canonically is
> `Ownable` by the following impl:
>
> unsafe impl<T: RefCounted> Ownable for T {
> unsafe fn release(this: NonNull<Self>) {
> T::dec_ref(this)
> }
> }
>
> So I don't think that we need this trait at all?
No. For an `ARef<T>` to be converted to an `Owned<T>` it requires a
`try_from_shared()` implementation. It is not even a given that the
function can implemented, if all the kernel exposes are some kind of
`inc_ref()` and `dec_ref()`.
Also there are more complicated cases like with `Mq::Request`, where the
existence of an `Owned<T>` cannot be represented by the same refcount value
as the existence of exactly one `ARef<T>`.
> > +///
> > +/// # Examples
>
> If we're having an example here, then we should also have on on `Owned`.
Yes, maybe. I mostly felt the need to create one for `OwnableRefCounted`
because it is a more complex idea than `Ownable`.
If I remember correctly, I didn't create one for `Owned`, as it should
probably more or less the same as for `ARef` and the one there has even
more problems of the kind you are pointing out. So maybe it would be best
to wait until someone fixes that and have the fixed version copied over to
`Owned` in the process?
> > +///
> > +/// A minimal example implementation of [`OwnableRefCounted`], [`Ownable`] and its usage with
> > +/// [`ARef`] and [`Owned`] looks like this:
> > +///
> > +/// ```
> > +/// # #![expect(clippy::disallowed_names)]
> > +/// use core::cell::Cell;
> > +/// use core::ptr::NonNull;
> > +/// use kernel::alloc::{flags, kbox::KBox, AllocError};
> > +/// use kernel::types::{
> > +/// ARef, RefCounted, Owned, Ownable, OwnableRefCounted,
> > +/// };
> > +///
> > +/// struct Foo {
> > +/// refcount: Cell<usize>,
> > +/// }
> > +///
> > +/// impl Foo {
> > +/// fn new() -> Result<Owned<Self>, AllocError> {
> > +/// // Use a `KBox` to handle the actual allocation.
> > +/// let result = KBox::new(
> > +/// Foo {
> > +/// refcount: Cell::new(1),
> > +/// },
> > +/// flags::GFP_KERNEL,
> > +/// )?;
> > +/// let result = NonNull::new(KBox::into_raw(result))
> > +/// .expect("Raw pointer to newly allocation KBox is null, this should never happen.");
>
> I'm not really convinced that an example using `KBox` is a good one...
> Maybe we should just have a local invisible `bindings` module that
> exposes a `-> *mut foo`. (internally it can just create a KBox`)
The example would become quite a bit more complicated then, no?
> > +/// // SAFETY: We just allocated the `Foo`, thus it is valid.
>
> This isn't going through all the requirements on `from_raw`...
Yes, this comment should probably be detailed.
Best,
Oliver
next prev parent reply other threads:[~2025-07-07 8:07 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <OYpTDi4YYXiWvLG3nO_8_WKsgOl9KOpun9l3a34m0jza6nmEWDCLTldSwCfZ2PRRprjXqGmrgSL2JN8rPOQH8Q==@protonmail.internalid>
2025-06-18 12:27 ` [PATCH v11 0/4] New trait OwnableRefCounted for ARef<->Owned conversion Oliver Mangold
2025-06-18 12:27 ` [PATCH v11 1/4] rust: types: Add Ownable/Owned types Oliver Mangold
2025-07-02 11:03 ` Benno Lossin
2025-07-07 6:58 ` Oliver Mangold
2025-07-07 9:23 ` Benno Lossin
2025-07-08 9:56 ` Oliver Mangold
2025-07-08 10:16 ` Miguel Ojeda
2025-07-08 13:06 ` Benno Lossin
2025-07-08 18:30 ` Andreas Hindborg
2025-07-08 19:18 ` Benno Lossin
2025-07-09 8:53 ` Andreas Hindborg
2025-07-09 9:11 ` Benno Lossin
2025-07-08 13:22 ` Andreas Hindborg
2025-07-08 14:53 ` Benno Lossin
2025-07-08 15:00 ` Benno Lossin
2025-07-07 12:26 ` Miguel Ojeda
2025-08-18 12:46 ` Andreas Hindborg
2025-08-18 13:04 ` Oliver Mangold
2025-08-18 22:27 ` Benno Lossin
2025-08-19 6:04 ` Oliver Mangold
2025-08-19 8:26 ` Benno Lossin
2025-08-19 8:45 ` Oliver Mangold
2025-08-19 9:00 ` Andreas Hindborg
2025-08-19 17:15 ` Benno Lossin
2025-08-20 10:48 ` Andreas Hindborg
2025-08-19 8:53 ` Andreas Hindborg
2025-08-19 17:13 ` Benno Lossin
2025-08-19 18:28 ` Andreas Hindborg
2025-08-20 6:02 ` Oliver Mangold
2025-08-20 7:41 ` Benno Lossin
2025-08-20 7:43 ` Oliver Mangold
2025-08-20 10:51 ` Andreas Hindborg
2025-06-18 12:27 ` [PATCH v11 2/4] rust: Split `AlwaysRefCounted` into two traits Oliver Mangold
2025-06-19 3:15 ` kernel test robot
2025-07-02 11:23 ` Benno Lossin
2025-07-07 7:42 ` Oliver Mangold
2025-07-07 9:27 ` Benno Lossin
2025-06-18 12:27 ` [PATCH v11 3/4] rust: Add missing SAFETY documentation for `ARef` example Oliver Mangold
2025-06-18 12:27 ` [PATCH v11 4/4] rust: Add `OwnableRefCounted` Oliver Mangold
2025-07-02 13:24 ` Benno Lossin
2025-07-07 8:07 ` Oliver Mangold [this message]
2025-07-07 9:33 ` Benno Lossin
2025-07-07 11:12 ` Andreas Hindborg
2025-07-07 11:47 ` Benno Lossin
2025-07-07 13:21 ` Andreas Hindborg
2025-07-07 15:39 ` Benno Lossin
2025-07-08 13:15 ` Andreas Hindborg
2025-07-08 14:50 ` Benno Lossin
2025-07-08 15:35 ` Andreas Hindborg
2025-07-08 9:36 ` Oliver Mangold
2025-07-08 13:42 ` Benno Lossin
2025-08-05 17:23 ` [PATCH v11 0/4] New trait OwnableRefCounted for ARef<->Owned conversion Danilo Krummrich
2025-08-06 5:56 ` Oliver Mangold
2025-08-15 10:12 ` Andreas Hindborg
2025-08-18 5:59 ` Oliver Mangold
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=aGuAR7JCrlmzQrx4@mango \
--to=oliver.mangold@pm.me \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=gary@garyguo.net \
--cc=lina+kernel@asahilina.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/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 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).