Assign callback to shared irq if there's no single irq line

This commit is contained in:
jiangjianfeng
2024-11-12 03:39:57 +00:00
committed by Tate, Hongliang Tian
parent 9965802f65
commit 38682e3ed9
4 changed files with 22 additions and 9 deletions

View File

@ -273,7 +273,10 @@ impl VirtioTransport for VirtioMmioTransport {
single_interrupt: bool, single_interrupt: bool,
) -> Result<(), VirtioTransportError> { ) -> Result<(), VirtioTransportError> {
if single_interrupt { 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); self.multiplex.write().register_queue_callback(func);
Ok(()) Ok(())

View File

@ -78,8 +78,12 @@ pub trait VirtioTransport: Sync + Send + Debug {
// ====================Device interrupt APIs===================== // ====================Device interrupt APIs=====================
/// Register queue interrupt callback. The transport will try to allocate single IRQ line if /// Registers a callback for queue interrupts.
/// `single_interrupt` is set. ///
/// 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( fn register_queue_callback(
&mut self, &mut self,
index: u16, index: u16,

View File

@ -208,11 +208,17 @@ impl VirtioTransport for VirtioPciTransport {
return Err(VirtioTransportError::InvalidArgs); return Err(VirtioTransportError::InvalidArgs);
} }
let (vector, irq) = if single_interrupt { let (vector, irq) = if single_interrupt {
self.msix_manager if let Some(unused_irq) = self.msix_manager.pop_unused_irq() {
.pop_unused_irq() unused_irq
.ok_or(VirtioTransportError::NotEnoughResources)? } else {
warn!(
"{:?}: `single_interrupt` ignored: no more IRQ lines available",
self.device_type()
);
self.msix_manager.shared_irq_line()
}
} else { } else {
self.msix_manager.shared_interrupt_irq() self.msix_manager.shared_irq_line()
}; };
irq.on_active(func); irq.on_active(func);
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select) field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)

View File

@ -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. /// Then this virtqueue should use shared interrupt IRQ.
/// This function will return the MSI-X vector and corresponding 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.shared_interrupt_vector,
self.msix self.msix