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,
) -> 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(())

View File

@ -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,

View File

@ -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 {
self.msix_manager.shared_interrupt_irq()
warn!(
"{:?}: `single_interrupt` ignored: no more IRQ lines available",
self.device_type()
);
self.msix_manager.shared_irq_line()
}
} else {
self.msix_manager.shared_irq_line()
};
irq.on_active(func);
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.
/// 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