All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Benno Lossin" <lossin@kernel.org>
To: "Oliver Mangold" <oliver.mangold@pm.me>
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 11:33:41 +0200	[thread overview]
Message-ID: <DB5PX74OB3DX.1UNT8MIBWNC2G@kernel.org> (raw)
In-Reply-To: <aGuAR7JCrlmzQrx4@mango>

On Mon Jul 7, 2025 at 10:07 AM CEST, Oliver Mangold wrote:
> On 250702 1524, Benno Lossin wrote:
>> On Wed Jun 18, 2025 at 2:27 PM CEST, Oliver Mangold wrote:
>> > @@ -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.

It's not needed as a safety requirement for implementing the trait. If
the implementation only contains sound code, then `Owned::from_raw`
should already ensure that `Owned<Self>` is only created if there is
exactly one reference to it.

>> > +/// - [`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()`.

I don't understand this paragraph.

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

Ah right, I forgot about this. What was the refcount characteristics of
this again?

*  1 = in flight, owned by C
*  2 = in flight, owned by Rust
* >2 = in flight, owned by Rust + additional references used by Rust
       code

Correct? Maybe @Andreas can check.

>> > +///
>> > +/// # 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?

Wait which problems on `ARef` do you mean? I disagree that `Owned` and
`ARef` have the same example. `Owned` should expose operations that
`ARef` can't otherwise there would be no value in using `Owned`.

>> > +///
>> > +/// 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?

Just hide those parts behind `#` lines in the example.

---
Cheers,
Benno

  reply	other threads:[~2025-07-07  9:33 UTC|newest]

Thread overview: 56+ 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-09-25  8:31       ` Oliver Mangold
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
2025-07-07  9:33         ` Benno Lossin [this message]
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=DB5PX74OB3DX.1UNT8MIBWNC2G@kernel.org \
    --to=lossin@kernel.org \
    --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=ojeda@kernel.org \
    --cc=oliver.mangold@pm.me \
    --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 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.