mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: Add a SyncCompletionQueue for the sync engines
The raw, qcow, and vhdx sync engines each carried an EventFd and a VecDeque of completions and repeated the same push and signal idiom at every completion site. Bundle the two into a SyncCompletionQueue with complete, notifier, and next_completed, and route the three engines through it. The repeated eventfd signal now lives in one place. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
9d3451a56a
commit
331b2bba53
@@ -4,20 +4,20 @@
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::io;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::async_io::{AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult};
|
||||
use crate::async_io::{
|
||||
AsyncIo, AsyncIoCompletion, AsyncIoError, AsyncIoOperation, AsyncIoResult, SyncCompletionQueue,
|
||||
};
|
||||
use crate::sparse::{punch_hole, write_zeroes};
|
||||
use crate::{AlignedFile, is_block_device};
|
||||
|
||||
pub(crate) struct RawSync {
|
||||
raw_file: AlignedFile,
|
||||
eventfd: EventFd,
|
||||
completion_list: VecDeque<AsyncIoCompletion>,
|
||||
completions: SyncCompletionQueue,
|
||||
alignment: u64,
|
||||
is_block_device: bool,
|
||||
}
|
||||
@@ -28,8 +28,7 @@ impl RawSync {
|
||||
let alignment = raw_file.alignment() as u64;
|
||||
RawSync {
|
||||
raw_file,
|
||||
eventfd: EventFd::new(libc::EFD_NONBLOCK).expect("Failed creating EventFd for RawFile"),
|
||||
completion_list: VecDeque::new(),
|
||||
completions: SyncCompletionQueue::new(),
|
||||
alignment,
|
||||
is_block_device,
|
||||
}
|
||||
@@ -38,7 +37,7 @@ impl RawSync {
|
||||
|
||||
impl AsyncIo for RawSync {
|
||||
fn notifier(&self) -> &EventFd {
|
||||
&self.eventfd
|
||||
self.completions.notifier()
|
||||
}
|
||||
|
||||
fn alignment(&self) -> u64 {
|
||||
@@ -61,9 +60,8 @@ impl AsyncIo for RawSync {
|
||||
unsafe { self.raw_file.write_vectored_at(iovecs, offset) }
|
||||
.map_err(AsyncIoError::WriteVectored)?
|
||||
} as i32;
|
||||
self.completion_list
|
||||
.push_back(AsyncIoCompletion::from_operation(op, result));
|
||||
self.eventfd.write(1).unwrap();
|
||||
self.completions
|
||||
.complete(AsyncIoCompletion::from_operation(op, result));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -76,33 +74,30 @@ impl AsyncIo for RawSync {
|
||||
}
|
||||
|
||||
if let Some(user_data) = user_data {
|
||||
self.completion_list
|
||||
.push_back(AsyncIoCompletion::new(user_data, result, None));
|
||||
self.eventfd.write(1).unwrap();
|
||||
self.completions
|
||||
.complete(AsyncIoCompletion::new(user_data, result, None));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn next_completed_request(&mut self) -> Option<AsyncIoCompletion> {
|
||||
self.completion_list.pop_front()
|
||||
self.completions.next_completed()
|
||||
}
|
||||
|
||||
fn punch_hole(&mut self, offset: u64, length: u64, user_data: u64) -> AsyncIoResult<()> {
|
||||
punch_hole(&mut self.raw_file, self.is_block_device, offset, length)
|
||||
.map_err(AsyncIoError::PunchHole)?;
|
||||
self.completion_list
|
||||
.push_back(AsyncIoCompletion::new(user_data, 0, None));
|
||||
self.eventfd.write(1).unwrap();
|
||||
self.completions
|
||||
.complete(AsyncIoCompletion::new(user_data, 0, None));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_zeroes(&mut self, offset: u64, length: u64, user_data: u64) -> AsyncIoResult<()> {
|
||||
write_zeroes(&mut self.raw_file, self.is_block_device, offset, length)
|
||||
.map_err(AsyncIoError::WriteZeroes)?;
|
||||
self.completion_list
|
||||
.push_back(AsyncIoCompletion::new(user_data, 0, None));
|
||||
self.eventfd.write(1).unwrap();
|
||||
self.completions
|
||||
.complete(AsyncIoCompletion::new(user_data, 0, None));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user