mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 17:03:23 +00:00
Assign callback to shared irq if there's no single irq line
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
9965802f65
commit
38682e3ed9
@ -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(())
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user