Re: [PATCH v2 2/5] rust: pci: resolve IRQ in vector() and embed IrqRequest in IrqVector
"Gary Guo" <[email protected]>
| Newsgroups | dev.linux.lists.driver-core,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> > Link: https://lore.kernel.org/all/[email protected]/ > Signed-off-by: Danilo Krummrich <[email protected]> > --- > 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) }) > } > } >