rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: Danilo Krummrich <dakr@redhat.com>,
	rafael@kernel.org, ojeda@kernel.org, alex.gaynor@gmail.com,
	wedsonaf@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com,
	benno.lossin@proton.me, a.hindborg@samsung.com,
	aliceryhl@google.com, tglx@linutronix.de, mingo@redhat.com,
	bp@alien8.de, dave.hansen@linux.intel.com,
	rust-for-linux@vger.kernel.org, x86@kernel.org, lyude@redhat.com,
	pstanner@redhat.com, ajanulgu@redhat.com, airlied@redhat.com,
	Asahi Lina <lina@asahilina.net>
Subject: Re: [PATCH 3/8] rust: device: Add a stub abstraction for devices
Date: Tue, 26 Mar 2024 12:03:27 -0700	[thread overview]
Message-ID: <ZgMb_2AphYylBYpZ@boqun-archlinux> (raw)
In-Reply-To: <2024032607-sheath-headlock-1fb2@gregkh>

On Tue, Mar 26, 2024 at 07:03:47PM +0100, Greg KH wrote:
[...]
> > > > +impl Clone for Device {
> > > > +    fn clone(&self) -> Self {
> > > > +        Self::from_dev(self)
> > > 
> > > Does this increment the reference count?
> > 
> > Yes, it does. from_dev() calls new() and new() calls get_device() again.
> 
> Ok, but why would you ever allow a device structure to be cloned?

This function actually doesn't clone the device structure, it rather
just clones the "smart pointer" to the device. But it's confusing since
it should use an extra layer of abstraction, as I mentioned:

	https://lore.kernel.org/rust-for-linux/ZgG7TlybSa00cuoy@boqun-archlinux/

Right now `Device` is mapped to `struct device *`, which mixes the
abstraction of a device struct and a pointer to a device struct. We
should do the abstraciton in a different way:

	// `Device` maps to `struct device`.
	#[repr(transparent)]
	struct Devcie(Opaque<bindings::device>);

and then having a `&Device` means you have a reference to the `Device`,
you can use it for any device related options except increase/descrease
the refcount of a device. For example:

	unsafe impl RawDevice for Device {
	    fn raw_device(&self) -> *mut bindings::device {
	        self.0.get()
	    }
	}

Driver code that only requires the existence of the device should only
use `&Device`.

And for the code that want to manage the lifetime of a device, since
`struct device` has a refcount in it, we can claim that `Device` is a
`AlwaysRefCounted` type:

	impl AlwaysRefCounted for Device {
	    fn inc_ref(&self) {
	        get_device(self.0.get());
	    }

	    unsafe fn dec_ref(obj: NonNull<Self>) {
	        put_device(obj.as_mut_ptr());
	    }
	}

with that, we have a type `ARef<Device>`, which is similar to `&Device`
in that it's a pointer type, but you can clone (inc refcount) and drop
(dec refcount) on it. We can still define a `Device::new` but the return
type is `ARef<Device>`, meaning we hold a reference to the device.

	impl Device {
	    pub unsafe fn new(ptr: NonNull<bindingds::device>) -> ARef<Device> {
	        unsafe { ARef::from_raw(ptr) }.clone()
	    }
	}

In this way, if Rust code is not the owner of the device (probably it's
the common case right now), Rust code can use a reference to make sure
it doesn't get freed by the owner. And of course, if it's a driver
callback where the driver guarantees the liveness of the device, the
Rust code should take a `&Device` and don't worry about the ownership
anymore.

Does this make sense?

Regards,
Boqun

> That's not something that should ever happen, once it is created, it is
> the ONLY instance of that structure around, and it can't be changed, as
> you passed it off to be handled by the driver core, and the driver core
> is the one that handles the lifetime of the object, NOT the bus or the
> driver that happens to bind to it.
> 
> I've been worried about how the interaction between the driver core and
> rust code is going to handle structure lifetime rules.  You need to be
> very careful here with what you do.  Rust code can create these
> structures, but once they are passed to the driver core, you lose the
> ability to control them and have to allow the driver core to manage
> them, as that's its job, not the rust code.
> 
> thanks,
> 
> greg k-h

  reply	other threads:[~2024-03-26 19:04 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-25 17:49 [PATCH 0/8] [RFC] Rust device / driver abstractions Danilo Krummrich
2024-03-25 17:49 ` [PATCH 1/8] arch: x86: tools: increase symbol name size Danilo Krummrich
2024-03-25 17:53   ` Miguel Ojeda
2024-03-25 18:01     ` Danilo Krummrich
2024-03-25 18:18       ` Miguel Ojeda
2024-03-25 17:49 ` [PATCH 2/8] rust: device: Add a minimal RawDevice trait Danilo Krummrich
2024-03-25 18:14   ` Greg KH
2024-03-25 18:22     ` Miguel Ojeda
2024-03-26 22:38     ` Danilo Krummrich
2024-03-27  5:25       ` Greg KH
2024-03-27 11:39         ` Danilo Krummrich
2024-03-25 17:49 ` [PATCH 3/8] rust: device: Add a stub abstraction for devices Danilo Krummrich
2024-03-25 17:58   ` Boqun Feng
2024-03-27 11:36     ` Danilo Krummrich
2024-03-25 18:14   ` Greg KH
2024-03-25 18:17   ` Greg KH
2024-03-26 16:01     ` Danilo Krummrich
2024-03-26 18:03       ` Greg KH
2024-03-26 19:03         ` Boqun Feng [this message]
2024-03-26 21:01         ` Danilo Krummrich
2024-03-27  1:38     ` Wedson Almeida Filho
2024-03-27  5:22       ` Greg KH
2024-03-27  9:05         ` Philipp Stanner
2024-03-27  9:13           ` Greg KH
2024-03-27 11:35         ` Danilo Krummrich
2024-03-25 17:49 ` [PATCH 4/8] rust: add driver abstraction Danilo Krummrich
2024-03-25 18:12   ` Greg KH
2024-03-25 18:30   ` Greg KH
2024-03-25 19:36     ` David Airlie
2024-03-26  5:37       ` Greg KH
2024-03-26  6:02         ` David Airlie
2024-03-26  6:14           ` Greg KH
2024-03-26  6:34             ` David Airlie
2024-03-31 19:17               ` Fabien Parent
2024-04-02 13:51                 ` Danilo Krummrich
2024-03-28 10:41   ` Viresh Kumar
2024-03-25 17:49 ` [PATCH 5/8] rust: add rcu abstraction Danilo Krummrich
2024-03-25 17:49 ` [PATCH 6/8] rust: add revocable mutex Danilo Krummrich
2024-03-25 18:22   ` Greg KH
2024-03-26 18:13     ` Danilo Krummrich
2024-03-26 18:17       ` Greg KH
2024-03-26 21:32         ` Danilo Krummrich
2024-03-25 17:49 ` [PATCH 7/8] rust: add revocable objects Danilo Krummrich
2024-03-25 18:21   ` Greg KH
2024-03-26 17:07     ` Danilo Krummrich
2024-03-26 18:16       ` Greg KH
2024-03-26 21:48         ` Danilo Krummrich
2024-03-27  1:31     ` Wedson Almeida Filho
2024-03-25 17:49 ` [PATCH 8/8] rust: add device::Data Danilo Krummrich
2024-03-25 18:21   ` Greg KH
2024-03-26 16:54     ` Danilo Krummrich
2024-03-26 18:12       ` Greg KH
2024-03-26 22:24         ` Danilo Krummrich

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=ZgMb_2AphYylBYpZ@boqun-archlinux \
    --to=boqun.feng@gmail.com \
    --cc=a.hindborg@samsung.com \
    --cc=airlied@redhat.com \
    --cc=ajanulgu@redhat.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=bp@alien8.de \
    --cc=dakr@redhat.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=lina@asahilina.net \
    --cc=lyude@redhat.com \
    --cc=mingo@redhat.com \
    --cc=ojeda@kernel.org \
    --cc=pstanner@redhat.com \
    --cc=rafael@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=wedsonaf@gmail.com \
    --cc=x86@kernel.org \
    /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).