From: "Benno Lossin" <lossin@kernel.org>
To: "Danilo Krummrich" <dakr@kernel.org>
Cc: "Daniel Almeida" <daniel.almeida@collabora.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
linux-pci@vger.kernel.org
Subject: Re: [PATCH v6 3/6] rust: irq: add support for non-threaded IRQs and handlers
Date: Sun, 13 Jul 2025 17:29:36 +0200 [thread overview]
Message-ID: <DBB18YX7MBDW.3C5Q5Y1O28NFL@kernel.org> (raw)
In-Reply-To: <DBAXP68U809C.2G8DMB52M3UZ7@kernel.org>
On Sun Jul 13, 2025 at 2:42 PM CEST, Danilo Krummrich wrote:
> On Sun Jul 13, 2025 at 2:16 PM CEST, Benno Lossin wrote:
>> On Sun Jul 13, 2025 at 1:57 PM CEST, Danilo Krummrich wrote:
>>> On Sun Jul 13, 2025 at 1:19 PM CEST, Benno Lossin wrote:
>>>> On Sun Jul 13, 2025 at 12:24 PM CEST, Danilo Krummrich wrote:
>>>>> On Sun Jul 13, 2025 at 1:32 AM CEST, Daniel Almeida wrote:
>>>>>>
>>>>>>
>>>>>>> On 12 Jul 2025, at 18:24, Danilo Krummrich <dakr@kernel.org> wrote:
>>>>>>>
>>>>>>> On Thu Jul 3, 2025 at 9:30 PM CEST, Daniel Almeida wrote:
>>>>>>>> +/// Callbacks for an IRQ handler.
>>>>>>>> +pub trait Handler: Sync {
>>>>>>>> + /// The hard IRQ handler.
>>>>>>>> + ///
>>>>>>>> + /// This is executed in interrupt context, hence all corresponding
>>>>>>>> + /// limitations do apply.
>>>>>>>> + ///
>>>>>>>> + /// All work that does not necessarily need to be executed from
>>>>>>>> + /// interrupt context, should be deferred to a threaded handler.
>>>>>>>> + /// See also [`ThreadedRegistration`].
>>>>>>>> + fn handle(&self) -> IrqReturn;
>>>>>>>> +}
>>>>>>>
>>>>>>> One thing I forgot, the IRQ handlers should have a &Device<Bound> argument,
>>>>>>> i.e.:
>>>>>>>
>>>>>>> fn handle(&self, dev: &Device<Bound>) -> IrqReturn
>>>>>>>
>>>>>>> IRQ registrations naturally give us this guarantee, so we should take advantage
>>>>>>> of that.
>>>>>>>
>>>>>>> - Danilo
>>>>>>
>>>>>> Hi Danilo,
>>>>>>
>>>>>> I do not immediately see a way to get a Device<Bound> from here:
>>>>>>
>>>>>> unsafe extern "C" fn handle_irq_callback<T: Handler>(_irq: i32, ptr: *mut c_void) -> c_uint {
>>>>>>
>>>>>> Refall that we've established `ptr` to be the address of the handler. This
>>>>>> came after some back and forth and after the extensive discussion that Benno
>>>>>> and Boqun had w.r.t to pinning in request_irq().
>>>>>
>>>>> You can just wrap the Handler in a new type and store the pointer there:
>>>>>
>>>>> #[pin_data]
>>>>> struct Wrapper {
>>>>> #[pin]
>>>>> handler: T,
>>>>> dev: NonNull<Device<Bound>>,
>>>>> }
>>>>>
>>>>> And then pass a pointer to the Wrapper field to request_irq();
>>>>> handle_irq_callback() can construct a &T and a &Device<Bound> from this.
>>>>>
>>>>> Note that storing a device pointer, without its own reference count, is
>>>>> perfectly fine, since inner (Devres<RegistrationInner>) already holds a
>>>>> reference to the device and guarantees the bound scope for the handler
>>>>> callbacks.
>>>>
>>>> Can't we just add an accessor function to `Devres`?
>>>
>>> #[pin_data]
>>> pub struct Registration<T: Handler + 'static> {
>>> #[pin]
>>> inner: Devres<RegistrationInner>,
>>>
>>> #[pin]
>>> handler: T,
>>>
>>> /// Pinned because we need address stability so that we can pass a pointer
>>> /// to the callback.
>>> #[pin]
>>> _pin: PhantomPinned,
>>> }
>>>
>>> Currently we pass the address of handler to request_irq(), so this doesn't help,
>>> hence my proposal to replace the above T with Wrapper (actually Wrapper<T>).
>>
>> You can just use `container_of!`?
>
> Sure, that's possible too.
>
>>>> Also `Devres` only stores `Device<Normal>`, not `Device<Bound>`...
>>>
>>> The Devres instance itself may out-live device unbind, but it ensures that the
>>> encapsulated data does not, hence it holds a reference count, i.e. ARef<Device>.
>>>
>>> Device<Bound> or ARef<Device<Bound>> *never* exists, only &'a Device<Bound>
>>> within a corresponding scope for which we can guarantee the device is bound.
>>>
>>> In the proposed wrapper we can store a NonNull<Device<Bound>> though, because we
>>> can safely give out a &Device<Bound> in the IRQ's handle() callback. This is
>>> because:
>>>
>>> (1) RegistrationInner is guarded by Devres and guarantees that free_irq() is
>>> completed *before* the device is unbound.
>>
>> How does it ensure that?
>
> RegistrationInner calls free_irq() in it's drop() method; Devres revokes it on
> device unbind.
Makes sense, so we probably do need the unsafe typestate change
function in this case.
>>>
>>> (2) It is guaranteed that the device pointer is valid because (1) guarantees
>>> it's even bound and because Devres<RegistrationInner> itself has a
>>> reference count.
>>
>> Yeah but I would find it much more natural (and also useful in other
>> circumstances) if `Devres<T>` would give you access to `Device` (at
>> least the `Normal` type state).
>
> If we use container_of!() instead or just pass the address of Self (i.e.
> Registration) to request_irq() instead,
>
> pub fn device(&self) -> &Device
>
> is absolutely possible to add to Devres, of course.
>
>> Depending on how (1) is ensured, we might just need an unsafe function
>> that turns `Device<Normal>` into `Device<Bound>`.
>
> `&Device<Normal>` in `&Device<Bound>`, yes. I have such a method locally
> already (but haven't sent it yet), because that's going to be a use-case for
> other abstractions as well. One specific example is the PWM Chip abstraction
> [1].
>
> [1] https://lore.kernel.org/lkml/20250710-rust-next-pwm-working-fan-for-sending-v11-3-93824a16f9ec@samsung.com/
I think this solution sounds much better than storing an additional
`NonNull<Device<Bound>>`.
---
Cheers,
Benno
next prev parent reply other threads:[~2025-07-13 15:31 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-03 19:29 [PATCH v6 0/6] rust: add support for request_irq Daniel Almeida
2025-07-03 19:29 ` [PATCH v6 1/6] rust: irq: add irq module Daniel Almeida
2025-07-04 7:43 ` Alice Ryhl
2025-07-03 19:30 ` [PATCH v6 2/6] rust: irq: add flags module Daniel Almeida
2025-07-04 6:14 ` Daniel Sedlak
2025-07-04 7:42 ` Alice Ryhl
2025-07-12 16:26 ` Daniel Almeida
2025-07-12 20:03 ` Alice Ryhl
2025-07-12 20:48 ` Daniel Almeida
2025-07-12 21:43 ` Alice Ryhl
2025-07-04 9:31 ` Miguel Ojeda
2025-07-03 19:30 ` [PATCH v6 3/6] rust: irq: add support for non-threaded IRQs and handlers Daniel Almeida
2025-07-04 7:51 ` Alice Ryhl
2025-07-07 16:18 ` Daniel Almeida
2025-07-07 20:30 ` Benno Lossin
2025-07-08 11:49 ` Alice Ryhl
2025-07-08 14:33 ` Benno Lossin
2025-07-04 16:39 ` Boqun Feng
2025-07-04 16:41 ` Boqun Feng
2025-07-07 7:20 ` Alice Ryhl
2025-07-08 12:15 ` Dirk Behme
2025-07-08 12:19 ` Danilo Krummrich
2025-07-12 21:24 ` Danilo Krummrich
2025-07-12 23:32 ` Daniel Almeida
2025-07-13 10:24 ` Danilo Krummrich
2025-07-13 11:19 ` Benno Lossin
2025-07-13 11:57 ` Danilo Krummrich
2025-07-13 12:16 ` Benno Lossin
2025-07-13 12:42 ` Danilo Krummrich
2025-07-13 14:09 ` Daniel Almeida
2025-07-13 14:19 ` Danilo Krummrich
2025-07-13 14:27 ` Danilo Krummrich
2025-07-13 14:48 ` Daniel Almeida
2025-07-13 15:02 ` Danilo Krummrich
[not found] ` <1F0227F0-8554-4DD2-BADE-0184D0824AF8@collabora.com>
2025-07-13 15:32 ` Daniel Almeida
2025-07-19 5:47 ` Dirk Behme
2025-07-19 8:56 ` Alice Ryhl
2025-07-20 0:45 ` Daniel Almeida
2025-07-14 7:57 ` Dirk Behme
2025-07-14 9:36 ` Danilo Krummrich
2025-07-13 15:29 ` Benno Lossin [this message]
2025-07-13 17:20 ` Danilo Krummrich
2025-07-14 6:42 ` Boqun Feng
2025-07-14 9:24 ` Danilo Krummrich
2025-07-14 10:29 ` Danilo Krummrich
2025-07-14 15:12 ` Daniel Almeida
2025-07-15 9:41 ` Benno Lossin
2025-07-15 12:33 ` Alice Ryhl
2025-07-15 12:37 ` Danilo Krummrich
2025-07-03 19:30 ` [PATCH v6 4/6] rust: irq: add support for threaded " Daniel Almeida
2025-07-04 7:53 ` Alice Ryhl
2025-07-03 19:30 ` [PATCH v6 5/6] rust: platform: add irq accessors Daniel Almeida
2025-07-04 7:56 ` Alice Ryhl
2025-07-04 18:17 ` Danilo Krummrich
2025-07-04 18:23 ` Danilo Krummrich
2025-07-03 19:30 ` [PATCH v6 6/6] rust: pci: " Daniel Almeida
2025-07-04 7:56 ` Alice Ryhl
2025-07-04 18:19 ` Danilo Krummrich
2025-07-04 18:29 ` Danilo Krummrich
2025-07-03 20:13 ` [PATCH v6 0/6] rust: add support for request_irq 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=DBB18YX7MBDW.3C5Q5Y1O28NFL@kernel.org \
--to=lossin@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tglx@linutronix.de \
--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 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.