Skip to content

Commit 61798a5

Browse files
committed
io_uring flush fixes
1 parent 005d92b commit 61798a5

File tree

7 files changed

+40
-15
lines changed

7 files changed

+40
-15
lines changed

src/vmm/src/device_manager/pci_mngr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ impl<'a> Persist<'a> for PciDevices {
311311
snapshotting yet"
312312
);
313313
} else {
314-
block_dev.prepare_save();
314+
block_dev.prepare_save()?;
315315
let device_state = block_dev.save();
316316
state.block_devices.push(VirtioDeviceState {
317317
device_id: block_dev.id().to_string(),

src/vmm/src/device_manager/persist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ impl<'a> Persist<'a> for MMIODeviceManager {
265265
snapshotting yet"
266266
);
267267
} else {
268-
block.prepare_save();
268+
block.prepare_save()?;
269269
let device_state = block.save();
270270
states.block_devices.push(VirtioDeviceState {
271271
device_id,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ impl Block {
8282
}
8383
}
8484

85-
pub fn prepare_save(&mut self) {
85+
pub fn prepare_save(&mut self) -> Result<(), BlockError> {
8686
match self {
87-
Self::Virtio(b) => b.prepare_save(),
88-
Self::VhostUser(b) => b.prepare_save(),
87+
Self::Virtio(b) => b.prepare_save().map_err(BlockError::VirtioBackend),
88+
Self::VhostUser(_) => Err(BlockError::InvalidBlockBackend),
8989
}
9090
}
9191

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

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -563,22 +563,32 @@ impl VirtioBlock {
563563
}
564564
}
565565

566-
fn drain_and_flush(&mut self, discard: bool) {
567-
if let Err(err) = self.disk.file_engine.drain_and_flush(discard) {
568-
error!("Failed to drain ops and flush block data: {:?}", err);
569-
}
566+
fn drain_and_flush(&mut self, discard: bool) -> Result<(), VirtioBlockError> {
567+
self.disk
568+
.file_engine
569+
.drain_and_flush(discard)
570+
.map_err(VirtioBlockError::FileEngine)
570571
}
571572

572573
/// Prepare device for being snapshotted.
573-
pub fn prepare_save(&mut self) {
574+
pub fn prepare_save(&mut self) -> Result<(), VirtioBlockError> {
574575
if !self.is_activated() {
575-
return;
576+
return Ok(());
576577
}
577578

578-
self.drain_and_flush(false);
579-
if let FileEngine::Async(ref _engine) = self.disk.file_engine {
579+
self.drain_and_flush(false)?;
580+
let is_async = matches!(self.disk.file_engine, FileEngine::Async(_));
581+
if is_async {
580582
self.process_async_completion_queue();
583+
if let FileEngine::Async(ref engine) = self.disk.file_engine {
584+
let pending = engine.pending_ops();
585+
if pending != 0 {
586+
return Err(VirtioBlockError::PendingAsyncOperations(pending));
587+
}
588+
}
581589
}
590+
591+
Ok(())
582592
}
583593
}
584594

@@ -682,7 +692,9 @@ impl Drop for VirtioBlock {
682692
}
683693
}
684694
CacheType::Writeback => {
685-
self.drain_and_flush(true);
695+
if let Err(err) = self.drain_and_flush(true) {
696+
error!("Failed to drain ops and flush block data: {:?}", err);
697+
}
686698
}
687699
};
688700
}
@@ -1673,7 +1685,7 @@ mod tests {
16731685
// Add a batch of flush requests.
16741686
add_flush_requests_batch(&mut block, &vq, 5);
16751687
simulate_queue_event(&mut block, None);
1676-
block.prepare_save();
1688+
block.prepare_save().unwrap();
16771689

16781690
// Check that all the pending flush requests were processed during `prepare_save()`.
16791691
check_flush_requests_batch(5, &vq);

src/vmm/src/devices/virtio/block/virtio/io/async_io.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ impl AsyncFileEngine {
119119
&self.completion_evt
120120
}
121121

122+
pub fn pending_ops(&self) -> u32 {
123+
self.ring.num_ops()
124+
}
125+
122126
pub fn push_read(
123127
&mut self,
124128
offset: u64,

src/vmm/src/devices/virtio/block/virtio/io/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ impl FileEngine {
172172
FileEngine::Sync(engine) => engine.flush().map_err(BlockIoError::Sync),
173173
}
174174
}
175+
176+
pub fn pending_async_ops(&self) -> u32 {
177+
match self {
178+
FileEngine::Async(engine) => engine.pending_ops(),
179+
FileEngine::Sync(_) => 0,
180+
}
181+
}
175182
}
176183

177184
#[cfg(test)]

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,6 @@ pub enum VirtioBlockError {
6363
RateLimiter(std::io::Error),
6464
/// Persistence error: {0}
6565
Persist(crate::devices::virtio::persist::PersistError),
66+
/// Async file engine still has {0} pending operations.
67+
PendingAsyncOperations(u32),
6668
}

0 commit comments

Comments
 (0)