Skip to content

Commit 91a4832

Browse files
committed
fix: asyncio not saving interrupt state
During prepare_save we must unconditionally trigger an interrupt to ensure the guest gets notified after restore. The guest may have suppressed notifications, but after snapshot/restore it needs to be woken up regardless. Fixes #5554 Signed-off-by: Constantine Peresypkin <pconstantine@gmail.com>
1 parent d130c7d commit 91a4832

File tree

1 file changed

+6
-4
lines changed
  • src/vmm/src/devices/virtio/block/virtio

1 file changed

+6
-4
lines changed

src/vmm/src/devices/virtio/block/virtio/device.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,13 @@ impl VirtioBlock {
468468
Ok(())
469469
}
470470

471-
fn process_async_completion_queue(&mut self) {
471+
fn process_async_completion_queue(&mut self, force_signal: bool) {
472472
let engine = unwrap_async_file_engine_or_return!(&mut self.disk.file_engine);
473473

474474
// This is safe since we checked in the event handler that the device is activated.
475475
let active_state = self.device_state.active_state().unwrap();
476476
let queue = &mut self.queues[0];
477+
let mut used_any = false;
477478

478479
loop {
479480
match engine.pop(&active_state.mem) {
@@ -504,12 +505,13 @@ impl VirtioBlock {
504505
finished.desc_idx, err
505506
)
506507
});
508+
used_any = true;
507509
}
508510
}
509511
}
510512
queue.advance_used_ring_idx();
511513

512-
if queue.prepare_kick() {
514+
if (force_signal && used_any) || queue.prepare_kick() {
513515
active_state
514516
.interrupt
515517
.trigger(VirtioInterruptType::Queue(0))
@@ -525,7 +527,7 @@ impl VirtioBlock {
525527
if let Err(err) = engine.completion_evt().read() {
526528
error!("Failed to get async completion event: {:?}", err);
527529
} else {
528-
self.process_async_completion_queue();
530+
self.process_async_completion_queue(false);
529531

530532
if self.is_io_engine_throttled {
531533
self.is_io_engine_throttled = false;
@@ -577,7 +579,7 @@ impl VirtioBlock {
577579

578580
self.drain_and_flush(false);
579581
if let FileEngine::Async(ref _engine) = self.disk.file_engine {
580-
self.process_async_completion_queue();
582+
self.process_async_completion_queue(true);
581583
}
582584
}
583585
}

0 commit comments

Comments
 (0)