rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Danilo Krummrich <dakr@kernel.org>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: Alice Ryhl <aliceryhl@google.com>,
	kernel@dakr.org, a.hindborg@kernel.org, alex.gaynor@gmail.com,
	benno.lossin@proton.me, bjorn3_gh@protonmail.com,
	boqun.feng@gmail.com, gary@garyguo.net,
	linux-kernel@vger.kernel.org, lyude@redhat.com,
	mairacanal@riseup.net, ojeda@kernel.org, rafael@kernel.org,
	rust-for-linux@vger.kernel.org, tmgross@umich.edu
Subject: Re: [PATCH 2/2] rust/faux: Add missing parent argument to Registration::new()
Date: Wed, 26 Feb 2025 11:39:31 +0100	[thread overview]
Message-ID: <Z77vYxUYVyFtW2lG@cassiopeiae> (raw)
In-Reply-To: <2025022659-spray-treble-759f@gregkh>

On Wed, Feb 26, 2025 at 10:58:17AM +0100, Greg KH wrote:
> On Wed, Feb 26, 2025 at 10:42:54AM +0100, Danilo Krummrich wrote:
> > On Wed, Feb 26, 2025 at 09:23:39AM +0000, Alice Ryhl wrote:
> > > On Wed, Feb 26, 2025 at 10:06 AM <kernel@dakr.org> wrote:
> > > >
> > > > On 2025-02-26 09:38, Alice Ryhl wrote:
> > > > > On Tue, Feb 25, 2025 at 10:31 PM Lyude Paul <lyude@redhat.com> wrote:
> > > > >>
> > > > >> A little late in the review of the faux device interface, we added the
> > > > >> ability to specify a parent device when creating new faux devices -
> > > > >> but
> > > > >> this never got ported over to the rust bindings. So, let's add the
> > > > >> missing
> > > > >> argument now so we don't have to convert other users later down the
> > > > >> line.
> > > > >>
> > > > >> Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > > >> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > > >> ---
> > > > >>  rust/kernel/faux.rs              | 10 ++++++++--
> > > > >>  samples/rust/rust_driver_faux.rs |  2 +-
> > > > >>  2 files changed, 9 insertions(+), 3 deletions(-)
> > > > >>
> > > > >> diff --git a/rust/kernel/faux.rs b/rust/kernel/faux.rs
> > > > >> index 41751403cd868..ae99ea3d114ef 100644
> > > > >> --- a/rust/kernel/faux.rs
> > > > >> +++ b/rust/kernel/faux.rs
> > > > >> @@ -23,11 +23,17 @@
> > > > >>
> > > > >>  impl Registration {
> > > > >>      /// Create and register a new faux device with the given name.
> > > > >> -    pub fn new(name: &CStr) -> Result<Self> {
> > > > >> +    pub fn new(name: &CStr, parent: Option<&device::Device>) ->
> > > > >> Result<Self> {
> > > > >>          // SAFETY:
> > > > >>          // - `name` is copied by this function into its own storage
> > > > >>          // - `faux_ops` is safe to leave NULL according to the C API
> > > > >> -        let dev = unsafe {
> > > > >> bindings::faux_device_create(name.as_char_ptr(), null_mut(), null())
> > > > >> };
> > > > >> +        let dev = unsafe {
> > > > >> +            bindings::faux_device_create(
> > > > >> +                name.as_char_ptr(),
> > > > >> +                parent.map_or(null_mut(), |p| p.as_raw()),
> > > > >> +                null(),
> > > > >
> > > > > This function signature only requires that `parent` is valid for the
> > > > > duration of this call to `new`, but `faux_device_create` stashes a
> > > > > pointer without touching the refcount. How do you ensure that the
> > > > > `parent` pointer does not become dangling?
> > > >
> > > > I was wondering the same, but it seems that the subsequent device_add()
> > > > call takes care of that:
> > > >
> > > > https://elixir.bootlin.com/linux/v6.14-rc3/source/drivers/base/core.c#L3588
> > > >
> > > > device_del() drops the reference.
> > > >
> > > > This makes device->parent only valid for the duration between
> > > > faux_device_create() and faux_device_remove().
> > > >
> > > > But this detail shouldn’t be relevant for this API.
> > > 
> > > I think this could use a few more comments to explain it. E.g.:
> > > 
> > > diff --git a/drivers/base/faux.c b/drivers/base/faux.c
> > > index 531e9d789ee0..674db8863d96 100644
> > > --- a/drivers/base/faux.c
> > > +++ b/drivers/base/faux.c
> > > @@ -131,6 +131,7 @@ struct faux_device *faux_device_create_with_groups(const char *name,
> > >  
> > >         device_initialize(dev);
> > >         dev->release = faux_device_release;
> > > +       /* The refcount of dev->parent is incremented in device_add. */
> > 
> > Yeah, this one is a bit odd to rely on a subsequent device_add() call, it
> > clearly deserves a comment.
> 
> What do you mean?  That's the way the driver model works, a parent
> always gets the reference count incremented as it can not go away until
> all of the children are gone.

That's all correct and I agree. I said it's a bit off because the reference is
not taken in the pointer assignment in faux_device_create_with_groups(), i.e.

	if (parent)
		dev->parent = parent;

but subsequently in device_add(). That doesn't make it obvious to the reader
that the driver core does indeed do the correct thing.

> 
> So if you pass a parent pointer into a "create" function in the driver
> core, it will be incremented, you don't have to worry about it.
> 
> I don't understand the issue with the rust binding here, it's not saving
> a pointer to the parent device, as long as it is valid going in, that's
> all that matters.

There's none, that's what I pointed out earlier too. :-)

> 
> 
> 
> > >         if (parent)
> > >                 dev->parent = parent;
> > >         else
> > > diff --git a/rust/kernel/faux.rs b/rust/kernel/faux.rs
> > > index 7673501ebe37..713ee6842e3f 100644
> > > --- a/rust/kernel/faux.rs
> > > +++ b/rust/kernel/faux.rs
> > > @@ -28,6 +28,7 @@ pub fn new(name: &CStr, parent: Option<&device::Device>) -> Result<Self> {
> > >          // SAFETY:
> > >          // - `name` is copied by this function into its own storage
> > >          // - `faux_ops` is safe to leave NULL according to the C API
> > > +        // - `faux_device_create` ensures that `parent` stays alive until `faux_device_destroy`.
> > 
> > Not sure that's a safety requirement for faux_device_create().
> 
> It's by default what the driver model does for you.
> 
> > The typical convention is that a caller must hold a reference to the object
> > behind the pointer when passing it to another function. If the callee decides
> > to store the pointer elsewhere, it's on the callee to take an additional
> > reference.
> 
> Exactly, the driver core handles this.

Agreed.

> 
> > I think if we want to add something to the safety comment, it should be somthing
> > along the line of "the type of `parent` implies that for the duration of this
> > call `parent` is a valid device with a non-zero reference count".
> 
> I don't understand the need for any safety comment about the parent
> here.  Again, as long as it is valid when the call is made, that is all
> that is needed.

Right, and we could mention that in the safety comment that something of the
type `&device::Device` is indeed valid by definition and hence fullfills the
requirement of faux_device_create() to get a valid pointer (or NULL).

  reply	other threads:[~2025-02-26 10:39 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-25 21:28 [PATCH 0/2] rust/faux: Minor binding fixes Lyude Paul
2025-02-25 21:29 ` [PATCH 1/2] rust/faux: Drop #[repr(transparent)] from faux::Registration Lyude Paul
2025-02-25 22:07   ` Danilo Krummrich
2025-02-26  8:39   ` Alice Ryhl
2025-02-26 12:59   ` Fiona Behrens
2025-02-25 21:29 ` [PATCH 2/2] rust/faux: Add missing parent argument to Registration::new() Lyude Paul
2025-02-25 22:07   ` Danilo Krummrich
2025-02-26  8:38   ` Alice Ryhl
2025-02-26  9:05     ` kernel
2025-02-26  9:03       ` kernel
2025-02-26  9:23       ` Alice Ryhl
2025-02-26  9:42         ` Danilo Krummrich
2025-02-26  9:51           ` Alice Ryhl
2025-02-26  9:58           ` Greg KH
2025-02-26 10:39             ` Danilo Krummrich [this message]
2025-02-26 11:01               ` Greg KH
2025-02-26 10:01   ` Greg Kroah-Hartman
2025-02-26 16:51     ` Lyude Paul
2025-02-26 19:31       ` Greg Kroah-Hartman

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=Z77vYxUYVyFtW2lG@cassiopeiae \
    --to=dakr@kernel.org \
    --cc=a.hindborg@kernel.org \
    --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=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel@dakr.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lyude@redhat.com \
    --cc=mairacanal@riseup.net \
    --cc=ojeda@kernel.org \
    --cc=rafael@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).