From 38682e3ed923c0ec7880f414267789a2ded06dbe Mon Sep 17 00:00:00 2001 From: jiangjianfeng Date: Tue, 12 Nov 2024 03:39:57 +0000 Subject: [PATCH] Assign callback to shared irq if there's no single irq line --- kernel/comps/virtio/src/transport/mmio/device.rs | 5 ++++- kernel/comps/virtio/src/transport/mod.rs | 8 ++++++-- kernel/comps/virtio/src/transport/pci/device.rs | 14 ++++++++++---- kernel/comps/virtio/src/transport/pci/msix.rs | 4 ++-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/kernel/comps/virtio/src/transport/mmio/device.rs b/kernel/comps/virtio/src/transport/mmio/device.rs index 31e394ab1..8bd5185f7 100644 --- a/kernel/comps/virtio/src/transport/mmio/device.rs +++ b/kernel/comps/virtio/src/transport/mmio/device.rs @@ -273,7 +273,10 @@ impl VirtioTransport for VirtioMmioTransport { single_interrupt: bool, ) -> Result<(), VirtioTransportError> { if single_interrupt { - return Err(VirtioTransportError::NotEnoughResources); + warn!( + "{:?}: `single_interrupt` ignored: no support for virtio-mmio devices", + self.device_type() + ); } self.multiplex.write().register_queue_callback(func); Ok(()) diff --git a/kernel/comps/virtio/src/transport/mod.rs b/kernel/comps/virtio/src/transport/mod.rs index e042710a3..766302223 100644 --- a/kernel/comps/virtio/src/transport/mod.rs +++ b/kernel/comps/virtio/src/transport/mod.rs @@ -78,8 +78,12 @@ pub trait VirtioTransport: Sync + Send + Debug { // ====================Device interrupt APIs===================== - /// Register queue interrupt callback. The transport will try to allocate single IRQ line if - /// `single_interrupt` is set. + /// Registers a callback for queue interrupts. + /// + /// If `single_interrupt` is enabled, the transport will initially + /// attempt to allocate a single IRQ line for the callback. + /// If no available IRQ lines are found for allocation, the + /// transport may assign the callback to a shared IRQ line. fn register_queue_callback( &mut self, index: u16, diff --git a/kernel/comps/virtio/src/transport/pci/device.rs b/kernel/comps/virtio/src/transport/pci/device.rs index f64559485..f2e05a597 100644 --- a/kernel/comps/virtio/src/transport/pci/device.rs +++ b/kernel/comps/virtio/src/transport/pci/device.rs @@ -208,11 +208,17 @@ impl VirtioTransport for VirtioPciTransport { return Err(VirtioTransportError::InvalidArgs); } let (vector, irq) = if single_interrupt { - self.msix_manager - .pop_unused_irq() - .ok_or(VirtioTransportError::NotEnoughResources)? + if let Some(unused_irq) = self.msix_manager.pop_unused_irq() { + unused_irq + } else { + warn!( + "{:?}: `single_interrupt` ignored: no more IRQ lines available", + self.device_type() + ); + self.msix_manager.shared_irq_line() + } } else { - self.msix_manager.shared_interrupt_irq() + self.msix_manager.shared_irq_line() }; irq.on_active(func); field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select) diff --git a/kernel/comps/virtio/src/transport/pci/msix.rs b/kernel/comps/virtio/src/transport/pci/msix.rs index f12ac7a0b..165147330 100644 --- a/kernel/comps/virtio/src/transport/pci/msix.rs +++ b/kernel/comps/virtio/src/transport/pci/msix.rs @@ -42,10 +42,10 @@ impl VirtioMsixManager { ) } - /// Get shared interrupt IRQ used by virtqueue. If a virtqueue will not send interrupt frequently. + /// Get shared IRQ line used by virtqueue. If a virtqueue will not send interrupt frequently. /// Then this virtqueue should use shared interrupt IRQ. /// This function will return the MSI-X vector and corresponding IRQ. - pub fn shared_interrupt_irq(&mut self) -> (u16, &mut IrqLine) { + pub fn shared_irq_line(&mut self) -> (u16, &mut IrqLine) { ( self.shared_interrupt_vector, self.msix