mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vm-device: support batch update interrupt source group GSI
Split interrupt source group restore into two steps, first restore the irqfd for each interrupt source entry, and second restore the GSI routing of the entire interrupt source group. This patch will reduce restore latency of interrupt source group, and in a 200-concurrent restore test, the patch reduced the average IOAPIC restore time from 15ms to 1ms. Signed-off-by: Yong He <alexyonghe@tencent.com>
This commit is contained in:
@@ -98,9 +98,14 @@ impl Gic {
|
||||
i as InterruptIndex,
|
||||
InterruptSourceConfig::LegacyIrq(config),
|
||||
false,
|
||||
false,
|
||||
)
|
||||
.map_err(Error::EnableInterrupt)?;
|
||||
}
|
||||
|
||||
self.interrupt_source_group
|
||||
.set_gsi()
|
||||
.map_err(Error::EnableInterrupt)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -237,9 +237,14 @@ impl Ioapic {
|
||||
if state.is_some() {
|
||||
for (irq, entry) in ioapic.used_entries.iter().enumerate() {
|
||||
if *entry {
|
||||
ioapic.update_entry(irq)?;
|
||||
ioapic.update_entry(irq, false)?;
|
||||
}
|
||||
}
|
||||
|
||||
ioapic
|
||||
.interrupt_source_group
|
||||
.set_gsi()
|
||||
.map_err(Error::UpdateInterrupt)?;
|
||||
}
|
||||
|
||||
Ok(ioapic)
|
||||
@@ -278,7 +283,7 @@ impl Ioapic {
|
||||
}
|
||||
// The entry must be updated through the interrupt source
|
||||
// group.
|
||||
if let Err(e) = self.update_entry(index) {
|
||||
if let Err(e) = self.update_entry(index, true) {
|
||||
error!("Failed updating IOAPIC entry: {:?}", e);
|
||||
}
|
||||
// Store the information this IRQ is now being used.
|
||||
@@ -329,7 +334,7 @@ impl Ioapic {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_entry(&self, irq: usize) -> Result<()> {
|
||||
fn update_entry(&self, irq: usize, set_gsi: bool) -> Result<()> {
|
||||
let entry = self.reg_entries[irq];
|
||||
|
||||
// Validate Destination Mode value, and retrieve Destination ID
|
||||
@@ -386,6 +391,7 @@ impl Ioapic {
|
||||
irq as InterruptIndex,
|
||||
InterruptSourceConfig::MsiIrq(config),
|
||||
interrupt_mask(entry) == 1,
|
||||
set_gsi,
|
||||
)
|
||||
.map_err(Error::UpdateInterrupt)?;
|
||||
|
||||
|
||||
@@ -361,10 +361,15 @@ mod tests {
|
||||
_index: InterruptIndex,
|
||||
_config: InterruptSourceConfig,
|
||||
_masked: bool,
|
||||
_set_gsi: bool,
|
||||
) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_gsi(&self) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
|
||||
Some(self.event_fd.try_clone().unwrap())
|
||||
}
|
||||
|
||||
@@ -413,10 +413,15 @@ mod tests {
|
||||
_index: InterruptIndex,
|
||||
_config: InterruptSourceConfig,
|
||||
_masked: bool,
|
||||
_set_gsi: bool,
|
||||
) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_gsi(&self) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
|
||||
Some(self.event_fd.try_clone().unwrap())
|
||||
}
|
||||
|
||||
@@ -365,9 +365,13 @@ mod tests {
|
||||
_index: InterruptIndex,
|
||||
_config: InterruptSourceConfig,
|
||||
_masked: bool,
|
||||
_set_gsi: bool,
|
||||
) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
fn set_gsi(&self) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
|
||||
Some(self.event_fd.try_clone().unwrap())
|
||||
}
|
||||
|
||||
@@ -485,9 +485,13 @@ mod tests {
|
||||
_index: InterruptIndex,
|
||||
_config: InterruptSourceConfig,
|
||||
_masked: bool,
|
||||
_set_gsi: bool,
|
||||
) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
fn set_gsi(&self) -> result::Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
|
||||
Some(self.event_fd.try_clone().unwrap())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user