public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: "Danilo Krummrich" <dakr@kernel.org>
To: "Alexandre Courbot" <acourbot@nvidia.com>
Cc: "Alice Ryhl" <aliceryhl@google.com>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	"John Hubbard" <jhubbard@nvidia.com>,
	"Alistair Popple" <apopple@nvidia.com>,
	"Joel Fernandes" <joelagnelf@nvidia.com>,
	"Timur Tabi" <ttabi@nvidia.com>, "Edwin Peer" <epeer@nvidia.com>,
	"Eliot Courtney" <ecourtney@nvidia.com>,
	nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	rust-for-linux@vger.kernel.org
Subject: Re: [PATCH 1/7] rust: pci: pass driver data by value to `unbind`
Date: Tue, 16 Dec 2025 13:14:00 +0100	[thread overview]
Message-ID: <DEZMS6Y4A7XE.XE7EUBT5SJFJ@kernel.org> (raw)
In-Reply-To: <20251216-nova-unload-v1-1-6a5d823be19d@nvidia.com>

On Tue Dec 16, 2025 at 6:13 AM CET, Alexandre Courbot wrote:
> When unbinding a PCI driver, the `T::unbind` callback is invoked by the
> driver framework, passing the driver data as a `Pin<&T>`.
>
> This artificially restricts what the driver can do, as it cannot mutate
> any state on the data. This becomes a problem in e.g. Nova, which needs
> to invoke mutable methods when unbinding.
>
> `remove_callback` retrieves the driver data by value, and drops it right
> after the call to `T::unbind`, meaning it is the only reference to the
> driver data by the time `T::unbind` is called.
>
> There is thus no reason for not granting full ownership of the data to
> `T::unbind`, so do it.

There are multiple reasons I did avoid this for:

(1) Race conditions

A driver can call Device::drvdata() and obtain a reference to the driver's
device private data as long as it has a &Device<Bound> and asserts the correct
type of the driver's device private data [1].

Assume you have an IRQ registration, for instance, that lives within this device
private data.  Within the IRQ handler, nothing prevents us from calling
Device::drvdata() given that the IRQ handler has a Device<Bound> reference.

Consequently, with passing the device private data by value to unbind() it can
happen that we have both a mutable and immutable reference at of the device
private data at the same time.

The same is true for a lot of other cases, such as work items or workqueues that
are scoped to the Device being bound living within the device private data.

More generally, you can't take full ownership of the device private data as long
as the device is not yet fully unbound (which is not yet the case in unbind()).

(2) Design

It is intentional that the device private data has a defined lifetime that ends
with the device being unbound from its driver. This way we get the guarantee
that any object stored in the device private data won't survive device / driver
unbind. If we give back the ownership to the driver, this guarantee is lost.

Conclusion:

Having that said, if you need mutable access to the fields of the device private
data within unbind() the corresponding field(s) should be protected by a lock.

Alternatively, you have mutable access within the destructor as well, but there
you don't have a bound device anymore. Which is only consequent, since we can't
call the destructor of the device private data before the device is fully
unbound.

(In fact, as by now, there is a bug with this, which I noticed a few days ago
when I still was on vacation: The bus implementations call the destructor of the
device private data too early, i.e. when the device is not fully unbound yet.

I'm working on a fix for this. Luckily, as by now, this is not a real bug in
practice, yet it has to be fixed.)

From your end you don't have to worry about this though. nova-core should just
employ a lock for this, as we will need it in the future anyways, since we will
have concurrent access to the GSP.

[1] https://rust.docs.kernel.org/kernel/device/struct.Device.html#method.drvdata

  reply	other threads:[~2025-12-16 12:14 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-16  5:13 [PATCH 0/7] gpu: nova-core: run unload sequence upon unbinding Alexandre Courbot
2025-12-16  5:13 ` [PATCH 1/7] rust: pci: pass driver data by value to `unbind` Alexandre Courbot
2025-12-16 12:14   ` Danilo Krummrich [this message]
2025-12-16 14:38     ` Alexandre Courbot
2025-12-16  5:13 ` [PATCH 2/7] rust: add warn_on_err macro Alexandre Courbot
2025-12-16  5:13 ` [PATCH 3/7] gpu: nova-core: use " Alexandre Courbot
2025-12-16  5:13 ` [PATCH RFC 4/7] rust: pin-init: allow `dead_code` on projection structure Alexandre Courbot
2025-12-16  6:12   ` Benno Lossin
2025-12-16  5:13 ` [PATCH 5/7] gpu: nova-nova: use pin-init projections Alexandre Courbot
2025-12-16  5:13 ` [PATCH 6/7] gpu: nova-core: send UNLOADING_GUEST_DRIVER GSP command GSP upon unloading Alexandre Courbot
2025-12-16 15:39   ` Joel Fernandes
2025-12-18 13:27     ` Alexandre Courbot
2025-12-18 20:52       ` Joel Fernandes
2025-12-19  3:26         ` Alexandre Courbot
2025-12-19  6:42           ` Joel Fernandes
2025-12-18 22:33       ` Timur Tabi
2025-12-18 22:44         ` Joel Fernandes
2025-12-18 23:34           ` Timur Tabi
2025-12-19  1:46             ` Joel Fernandes
2025-12-19  1:48               ` Joel Fernandes
2025-12-19  3:39         ` Alexandre Courbot
2025-12-20 21:30           ` Timur Tabi
2026-01-14 14:02             ` Alexandre Courbot
2025-12-16  5:13 ` [PATCH 7/7] gpu: nova-core: run Booter Unloader and FWSEC-SB upon unbinding Alexandre Courbot

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=DEZMS6Y4A7XE.XE7EUBT5SJFJ@kernel.org \
    --to=dakr@kernel.org \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=apopple@nvidia.com \
    --cc=bhelgaas@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ecourtney@nvidia.com \
    --cc=epeer@nvidia.com \
    --cc=gary@garyguo.net \
    --cc=jhubbard@nvidia.com \
    --cc=joelagnelf@nvidia.com \
    --cc=kwilczynski@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tmgross@umich.edu \
    --cc=ttabi@nvidia.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox