Re: [PATCH v2 2/5] rust: pci: resolve IRQ in vector() and embed IrqRequest in IrqVector

From: Gary Guo

Date: Wed Aug 12 2026 - 12:46:26 EST


On Wed Aug 12, 2026 at 12:39 AM BST, Danilo Krummrich wrote:
> Move the pci_irq_vector() call from the TryInto<IrqRequest> impl into
> IrqVectorRegistration::vector(), so the IRQ number is resolved eagerly.
>
> IrqVector now embeds the resolved IrqRequest and the vector index. The
> conversion to IrqRequest is infallible (From instead of TryInto), which
> removes the need for pin_init_scope in request_irq/request_threaded_irq.
>
> Inspired-by: John Hubbard <jhubbard@xxxxxxxxxx>
> Link: https://lore.kernel.org/all/20260808031120.363869-3-jhubbard@xxxxxxxxxx/
> Signed-off-by: Danilo Krummrich <dakr@xxxxxxxxxx>
> ---
> rust/kernel/pci/irq.rs | 77 ++++++++++++++++++++----------------------
> 1 file changed, 37 insertions(+), 40 deletions(-)
>
> diff --git a/rust/kernel/pci/irq.rs b/rust/kernel/pci/irq.rs
> index 8e0651587829..305701440114 100644
> --- a/rust/kernel/pci/irq.rs
> +++ b/rust/kernel/pci/irq.rs
>
> [snip]
>
> -impl<'a> TryInto<IrqRequest<'a>> for IrqVector<'a> {
> - type Error = Error;
> -
> - fn try_into(self) -> Result<IrqRequest<'a>> {
> - // SAFETY: `self.dev.as_raw()` returns a valid pointer to a `struct pci_dev`.
> - let irq = unsafe { bindings::pci_irq_vector(self.dev.as_raw(), self.index()) };
> - if irq < 0 {
> - return Err(crate::error::Error::from_errno(irq));
> - }
> - // SAFETY: `irq` is guaranteed to be a valid IRQ number for `self.dev`.
> - Ok(unsafe { IrqRequest::new(self.dev.as_ref(), irq as u32) })
> +impl<'a> From<IrqVector<'a>> for IrqRequest<'a> {
> + #[inline]
> + fn from(vector: IrqVector<'a>) -> Self {
> + vector.request
> }
> }
>
> @@ -142,15 +143,19 @@ pub fn vector_count(&self) -> usize {
> ///
> /// The returned [`IrqVector`] borrows from this registration, ensuring the vector allocation
> /// remains live while any handler is registered on it.
> - #[inline]
> pub fn vector(&self, index: usize) -> Result<IrqVector<'_>> {
> if index >= self.count.get() {
> return Err(EINVAL);
> }
>
> - // SAFETY: `index` is within bounds of this registration's allocation, and `self.dev` is
> - // the device it was allocated from.
> - Ok(unsafe { IrqVector::new(self.dev, self, index as u32) })
> + // SAFETY: `self.dev.as_raw()` is a valid pointer to a `struct pci_dev`.
> + let irq = unsafe { bindings::pci_irq_vector(self.dev.as_raw(), index as u32) };
> + if irq < 0 {
> + return Err(Error::from_errno(irq));
> + }

Correct me if I'm wrong, but I believe that it's impossible for `pci_irq_vector`
once we have allocated vector and the index is in bounds. (If that's not the
case, we should ideally fix that instead.)

So I think we should just `.expect()` on the error in `Into`.

Best,
Gary

> +
> + // SAFETY: `irq` is a valid IRQ number for `self.dev`, resolved from this registration.
> + Ok(unsafe { IrqVector::new(IrqRequest::new(self.dev.as_ref(), irq as u32), self, index) })
> }
> }
>