[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2026010741-wiry-trophy-46ec@gregkh>
Date: Wed, 7 Jan 2026 13:22:44 +0100
From: Greg KH <gregkh@...uxfoundation.org>
To: Danilo Krummrich <dakr@...nel.org>
Cc: rafael@...nel.org, igor.korotin.linux@...il.com, ojeda@...nel.org,
boqun.feng@...il.com, gary@...yguo.net, bjorn3_gh@...tonmail.com,
lossin@...nel.org, a.hindborg@...nel.org, aliceryhl@...gle.com,
tmgross@...ch.edu, david.m.ertman@...el.com, ira.weiny@...el.com,
leon@...nel.org, bhelgaas@...gle.com, kwilczynski@...nel.org,
wsa+renesas@...g-engineering.com, linux-kernel@...r.kernel.org,
rust-for-linux@...r.kernel.org, linux-pci@...r.kernel.org,
linux-usb@...r.kernel.org, linux-i2c@...r.kernel.org
Subject: Re: [PATCH 6/6] rust: driver: drop device private data post unbind
On Wed, Jan 07, 2026 at 11:35:05AM +0100, Danilo Krummrich wrote:
> @@ -548,6 +548,10 @@ static DEVICE_ATTR_RW(state_synced);
> static void device_unbind_cleanup(struct device *dev)
> {
> devres_release_all(dev);
> +#ifdef CONFIG_RUST
Nit, let's not put #ifdef in .c files, the overhead of an empty pointer
for all drivers is not a big deal.
> + if (dev->driver->p_cb.post_unbind)
> + dev->driver->p_cb.post_unbind(dev);
> +#endif
> arch_teardown_dma_ops(dev);
> kfree(dev->dma_range_map);
> dev->dma_range_map = NULL;
> diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
> index cd8e0f0a634b..51a9ebdd8a2d 100644
> --- a/include/linux/device/driver.h
> +++ b/include/linux/device/driver.h
> @@ -85,6 +85,8 @@ enum probe_type {
> * uevent.
> * @p: Driver core's private data, no one other than the driver
> * core can touch this.
> + * @p_cb: Callbacks private to the driver core; no one other than the
> + * driver core is allowed to touch this.
> *
> * The device driver-model tracks all of the drivers known to the system.
> * The main reason for this tracking is to enable the driver core to match
> @@ -119,6 +121,15 @@ struct device_driver {
> void (*coredump) (struct device *dev);
>
> struct driver_private *p;
> +#ifdef CONFIG_RUST
Again, no #ifdef.
> + struct {
> + /*
> + * Called after remove() and after all devres entries have been
> + * processed.
> + */
> + void (*post_unbind)(struct device *dev);
post_unbind_rust_only()?
> -impl<T: RegistrationOps> Registration<T> {
> +impl<T: RegistrationOps + 'static> Registration<T> {
> + extern "C" fn post_unbind_callback(dev: *mut bindings::device) {
> + // SAFETY: The driver core only ever calls the post unbind callback with a valid pointer to
> + // a `struct device`.
> + //
> + // INVARIANT: `dev` is valid for the duration of the `post_unbind_callback()`.
> + let dev = unsafe { &*dev.cast::<device::Device<device::CoreInternal>>() };
> +
> + // `remove()` and all devres callbacks have been completed at this point, hence drop the
> + // driver's device private data.
> + //
> + // SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the
> + // driver's device private data.
> + drop(unsafe { dev.drvdata_obtain::<T::DriverData>() });
I don't mind this, but why don't we also do this for all C drivers?
Just null out the pointer at this point in time so that no one can touch
it, just like you are doing here (in a way.)
thanks,
greg k-h
Powered by blists - more mailing lists