From: Danilo Krummrich <dakr@kernel.org>
To: Benno Lossin <benno.lossin@proton.me>
Cc: "Boqun Feng" <boqun.feng@gmail.com>,
"Alice Ryhl" <aliceryhl@google.com>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Wedson Almeida Filho" <wedsonaf@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@samsung.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Viresh Kumar" <viresh.kumar@linaro.org>,
"Danilo Krummrich" <dakr@redhat.com>,
"Trevor Gross" <tmgross@umich.edu>,
gregkh@linuxfoundation.org
Subject: Re: [RFC PATCH] rust: types: Add explanation for ARef pattern
Date: Fri, 26 Jul 2024 18:19:48 +0200 [thread overview]
Message-ID: <ZqPMpNNq0Q0S-M2P@cassiopeiae> (raw)
In-Reply-To: <8641453e-664d-4290-b9bc-4a2567ddc3fe@proton.me>
On Fri, Jul 26, 2024 at 03:54:37PM +0000, Benno Lossin wrote:
> On 26.07.24 17:15, Boqun Feng wrote:
> > On Fri, Jul 26, 2024 at 02:42:36PM +0000, Benno Lossin wrote:
> >> On 26.07.24 16:26, Boqun Feng wrote:
> >>> On Fri, Jul 26, 2024 at 01:43:38PM +0000, Benno Lossin wrote:
> >>> [...]
> >>>>>>
> >>>>>> You can always get a `&T` from `ARef<T>`, since it implements `Deref`.
> >>>>>>
> >>>>>
> >>>>> Yeah, but this is unrelated. I was talking about that API providers can
> >>>>> decide whether they want to only provide a `raw_ptr` -> `ARef<Self>` if
> >>>>> they don't need to provide a `raw_ptr` -> `&Self`.
> >>>>>
> >>>>>>> Overall, I feel like we don't necessarily make a preference between
> >>>>>>> `->&Self` and `->ARef<Self>` functions here, since it's up to the users'
> >>>>>>> design?
> >>>>>>
> >>>>>> I would argue that there should be a clear preference for functions
> >>>>>> returning `&Self` when possible (ie there is a parameter that the
> >>>>>
> >>>>> If "possible" also means there's going to be `raw_ptr` -> `&Self`
> >>>>> function (as the same publicity level) anyway, then agreed. In other
> >>>>> words, if the users only need the `raw_ptr` -> `ARef<Self>`
> >>>>> functionality, we don't want to force people to provide a `raw_ptr` ->
> >>>>> `&Self` just because, right?
> >>>>
> >>>> I see... I am having a hard time coming up with an example where users
> >>>> would exclusively want `ARef<Self>` though... What do you have in mind?
> >>>> Normally types wrapped by `ARef` have `&self` methods.
> >>>>
> >>>
> >>> Having `&self` methods doesn't mean the necessarity of a `raw_ptr` ->
> >>> `&Self` function, for example, a `Foo` is wrapped as follow:
> >>>
> >>> struct Foo(Opaque<foo>);
> >>> impl Foo {
> >>> pub fn bar(&self) -> Bar { ... }
> >>> pub unsafe fn get_foo(ptr: *mut foo) -> ARef<Foo> { ... }
> >>> }
> >>>
> >>> in this case, the abstration provider may not want user to get a
> >>> `raw_ptr` -> `&Self` function, so no need to have it.
> >>
> >> I don't understand this, why would the abstraction provider do that? The
> >
> > Because no user really needs to convert a `raw_ptr` to a `&Self` whose
> > lifetime is limited to a scope?
>
> What if you have this:
>
> unsafe extern "C" fn called_from_c_via_vtable(foo: *mut bindings::foo) {
> // SAFETY: ...
> let foo = unsafe { Foo::from_raw(foo) };
> foo.bar();
> }
>
> In this case, there is no need to take a refcount on `foo`.
>
> > Why do we provide a function if no one needs and the solely purpose is
> > to just avoid providing another function?
>
> I don't think that there should be a lot of calls to that function
> anyways and thus I don't think there is value in providing two functions
> for almost the same behavior. Since one can be derived by the other, I
> would go for only implementing the first one.
I don't think there should be a rule saying that we can't provide a wrapper
function for deriving an `ARef<T>`. `Device` is a good example:
`let dev: ARef<Device> = unsafe { Device::from_raw(raw_dev) }.into();`
vs.
`let dev = unsafe { Device::get(raw_dev) };`
To me personally, the latter looks quite a bit cleaner.
Besides that, I think every kernel engineer (even without Rust background) will
be able to decode the meaning of this call. And if we get the chance to make
things obvious to everyone *without* the need to make a compromise, we should
clearly take it.
>
> >> user can already get a `&Foo` reference, so what's the harm having a
> >> function supplying that directly?
> >
> > Getting a `&Foo` from a `ARef<Foo>` is totally different than getting a
> > `&Foo` from a pointer, right? And it's OK for an abstraction provider to
> > want to avoid that.
> >
> > Another example that you may not want to provide a `-> &Self` function
> > is:
> > struct Foo(Opaque<foo>);
> > impl Foo {
> > pub fn bar(&self) -> Bar { ... }
> > pub fn find_foo(idx: u32) -> ARef<Foo> { ... }
> > }
> >
> > in other words, you have a query function (idx -> *mut foo), and I think
> > in this case, you would avoid `find_foo(idx: u32) -> &Foo`, right?
>
> Yes, this is the exception I had in mind with "if possible (ie there is
> a parameter that the lifetime can bind to)" (in this case there wouldn't
> be such a parameter).
>
> > Honestly, this discussion has been going to a rabit hole. I will mention
> > and already mentioned the conversion `&Self` -> `ARef<Self>`. Leaving
> > the preference part blank is fine to me, since if it's a good practice,
> > then everybody will follow, otherwise, we are missing something here.
> > Just trying to not make a descision for the users...
>
> Sure.
>
> ---
> Cheers,
> Benno
>
next prev parent reply other threads:[~2024-07-26 16:20 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-10 3:24 [RFC PATCH] rust: types: Add explanation for ARef pattern Boqun Feng
2024-07-23 9:14 ` Alice Ryhl
2024-07-24 17:44 ` Boqun Feng
2024-07-25 18:12 ` Benno Lossin
2024-07-25 20:29 ` Boqun Feng
2024-07-26 13:43 ` Benno Lossin
2024-07-26 14:26 ` Boqun Feng
2024-07-26 14:42 ` Benno Lossin
2024-07-26 15:15 ` Boqun Feng
2024-07-26 15:54 ` Benno Lossin
2024-07-26 16:19 ` Danilo Krummrich [this message]
2024-07-29 11:31 ` Alice Ryhl
2024-07-31 14:48 ` Benno Lossin
2024-07-25 18:51 ` Benno Lossin
2024-07-25 20:06 ` Boqun Feng
2024-07-25 20:32 ` Benno Lossin
2024-07-25 20:43 ` 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=ZqPMpNNq0Q0S-M2P@cassiopeiae \
--to=dakr@kernel.org \
--cc=a.hindborg@samsung.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=corbet@lwn.net \
--cc=dakr@redhat.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=viresh.kumar@linaro.org \
--cc=wedsonaf@gmail.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.