mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 11:25:20 +00:00
vmm: Rely on virtio-blk io_uring when possible
In case the host supports io_uring and the specific io_uring options needed, the VMM will choose the asynchronous version of virtio-blk. This will enable better I/O performances compared to the default synchronous version. This is also important to note the VMM won't be able to use the asynchronous version if the backend image is in QCOW format. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
64283726e7
commit
917027c55b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1613,6 +1613,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"arch",
|
"arch",
|
||||||
|
"block_util",
|
||||||
"clap",
|
"clap",
|
||||||
"credibility",
|
"credibility",
|
||||||
"devices",
|
"devices",
|
||||||
|
@ -19,6 +19,7 @@ clap = "2.33.1"
|
|||||||
acpi_tables = { path = "../acpi_tables", optional = true }
|
acpi_tables = { path = "../acpi_tables", optional = true }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
arch = { path = "../arch" }
|
arch = { path = "../arch" }
|
||||||
|
block_util = { path = "../block_util" }
|
||||||
devices = { path = "../devices" }
|
devices = { path = "../devices" }
|
||||||
epoll = ">=4.0.1"
|
epoll = ">=4.0.1"
|
||||||
hypervisor = { path = "../hypervisor" }
|
hypervisor = { path = "../hypervisor" }
|
||||||
|
@ -32,6 +32,7 @@ use arch::layout;
|
|||||||
use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
|
use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use arch::DeviceType;
|
use arch::DeviceType;
|
||||||
|
use block_util::block_io_uring_is_supported;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use devices::gic;
|
use devices::gic;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -1662,70 +1663,95 @@ impl DeviceManager {
|
|||||||
)
|
)
|
||||||
.map_err(DeviceManagerError::Disk)?;
|
.map_err(DeviceManagerError::Disk)?;
|
||||||
|
|
||||||
let mut raw_img = qcow::RawFile::new(image, disk_cfg.direct);
|
let mut raw_img = qcow::RawFile::new(image.try_clone().unwrap(), disk_cfg.direct);
|
||||||
|
|
||||||
let image_type = qcow::detect_image_type(&mut raw_img)
|
let image_type = qcow::detect_image_type(&mut raw_img)
|
||||||
.map_err(DeviceManagerError::DetectImageType)?;
|
.map_err(DeviceManagerError::DetectImageType)?;
|
||||||
match image_type {
|
let (virtio_device, migratable_device) = match image_type {
|
||||||
ImageType::Raw => {
|
ImageType::Raw => {
|
||||||
let dev = virtio_devices::Block::new(
|
// Use asynchronous backend relying on io_uring if the
|
||||||
id.clone(),
|
// syscalls are supported.
|
||||||
raw_img,
|
if block_io_uring_is_supported() {
|
||||||
disk_cfg
|
let dev = Arc::new(Mutex::new(
|
||||||
.path
|
virtio_devices::BlockIoUring::new(
|
||||||
.as_ref()
|
id.clone(),
|
||||||
.ok_or(DeviceManagerError::NoDiskPath)?
|
image,
|
||||||
.clone(),
|
disk_cfg
|
||||||
disk_cfg.readonly,
|
.path
|
||||||
disk_cfg.iommu,
|
.as_ref()
|
||||||
disk_cfg.num_queues,
|
.ok_or(DeviceManagerError::NoDiskPath)?
|
||||||
disk_cfg.queue_size,
|
.clone(),
|
||||||
)
|
disk_cfg.readonly,
|
||||||
.map_err(DeviceManagerError::CreateVirtioBlock)?;
|
disk_cfg.iommu,
|
||||||
|
disk_cfg.num_queues,
|
||||||
|
disk_cfg.queue_size,
|
||||||
|
)
|
||||||
|
.map_err(DeviceManagerError::CreateVirtioBlock)?,
|
||||||
|
));
|
||||||
|
|
||||||
let block = Arc::new(Mutex::new(dev));
|
(
|
||||||
|
Arc::clone(&dev) as VirtioDeviceArc,
|
||||||
|
dev as Arc<Mutex<dyn Migratable>>,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let dev = Arc::new(Mutex::new(
|
||||||
|
virtio_devices::Block::new(
|
||||||
|
id.clone(),
|
||||||
|
raw_img,
|
||||||
|
disk_cfg
|
||||||
|
.path
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(DeviceManagerError::NoDiskPath)?
|
||||||
|
.clone(),
|
||||||
|
disk_cfg.readonly,
|
||||||
|
disk_cfg.iommu,
|
||||||
|
disk_cfg.num_queues,
|
||||||
|
disk_cfg.queue_size,
|
||||||
|
)
|
||||||
|
.map_err(DeviceManagerError::CreateVirtioBlock)?,
|
||||||
|
));
|
||||||
|
|
||||||
// Fill the device tree with a new node. In case of restore, we
|
(
|
||||||
// know there is nothing to do, so we can simply override the
|
Arc::clone(&dev) as VirtioDeviceArc,
|
||||||
// existing entry.
|
dev as Arc<Mutex<dyn Migratable>>,
|
||||||
self.device_tree
|
)
|
||||||
.lock()
|
}
|
||||||
.unwrap()
|
|
||||||
.insert(id.clone(), device_node!(id, block));
|
|
||||||
|
|
||||||
Ok((Arc::clone(&block) as VirtioDeviceArc, disk_cfg.iommu, id))
|
|
||||||
}
|
}
|
||||||
ImageType::Qcow2 => {
|
ImageType::Qcow2 => {
|
||||||
let qcow_img =
|
let qcow_img =
|
||||||
QcowFile::from(raw_img).map_err(DeviceManagerError::QcowDeviceCreate)?;
|
QcowFile::from(raw_img).map_err(DeviceManagerError::QcowDeviceCreate)?;
|
||||||
let dev = virtio_devices::Block::new(
|
let dev = Arc::new(Mutex::new(
|
||||||
id.clone(),
|
virtio_devices::Block::new(
|
||||||
qcow_img,
|
id.clone(),
|
||||||
disk_cfg
|
qcow_img,
|
||||||
.path
|
disk_cfg
|
||||||
.as_ref()
|
.path
|
||||||
.ok_or(DeviceManagerError::NoDiskPath)?
|
.as_ref()
|
||||||
.clone(),
|
.ok_or(DeviceManagerError::NoDiskPath)?
|
||||||
disk_cfg.readonly,
|
.clone(),
|
||||||
disk_cfg.iommu,
|
disk_cfg.readonly,
|
||||||
disk_cfg.num_queues,
|
disk_cfg.iommu,
|
||||||
disk_cfg.queue_size,
|
disk_cfg.num_queues,
|
||||||
|
disk_cfg.queue_size,
|
||||||
|
)
|
||||||
|
.map_err(DeviceManagerError::CreateVirtioBlock)?,
|
||||||
|
));
|
||||||
|
|
||||||
|
(
|
||||||
|
Arc::clone(&dev) as VirtioDeviceArc,
|
||||||
|
dev as Arc<Mutex<dyn Migratable>>,
|
||||||
)
|
)
|
||||||
.map_err(DeviceManagerError::CreateVirtioBlock)?;
|
|
||||||
|
|
||||||
let block = Arc::new(Mutex::new(dev));
|
|
||||||
|
|
||||||
// Fill the device tree with a new node. In case of restore, we
|
|
||||||
// know there is nothing to do, so we can simply override the
|
|
||||||
// existing entry.
|
|
||||||
self.device_tree
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.insert(id.clone(), device_node!(id, block));
|
|
||||||
|
|
||||||
Ok((Arc::clone(&block) as VirtioDeviceArc, disk_cfg.iommu, id))
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
// Fill the device tree with a new node. In case of restore, we
|
||||||
|
// know there is nothing to do, so we can simply override the
|
||||||
|
// existing entry.
|
||||||
|
self.device_tree
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(id.clone(), device_node!(id, migratable_device));
|
||||||
|
|
||||||
|
Ok((virtio_device, disk_cfg.iommu, id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,11 @@ macro_rules! or {
|
|||||||
($($x:expr),*) => (vec![$($x),*])
|
($($x:expr),*) => (vec![$($x),*])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Define io_uring syscalls as they are not yet part of libc.
|
||||||
|
const SYS_IO_URING_SETUP: i64 = 425;
|
||||||
|
const SYS_IO_URING_ENTER: i64 = 426;
|
||||||
|
const SYS_IO_URING_REGISTER: i64 = 427;
|
||||||
|
|
||||||
// See include/uapi/asm-generic/ioctls.h in the kernel code.
|
// See include/uapi/asm-generic/ioctls.h in the kernel code.
|
||||||
const TCGETS: u64 = 0x5401;
|
const TCGETS: u64 = 0x5401;
|
||||||
const TCSETS: u64 = 0x5402;
|
const TCSETS: u64 = 0x5402;
|
||||||
@ -279,6 +284,9 @@ pub fn vmm_thread_filter() -> Result<SeccompFilter, Error> {
|
|||||||
allow_syscall(libc::SYS_gettimeofday),
|
allow_syscall(libc::SYS_gettimeofday),
|
||||||
allow_syscall(libc::SYS_getuid),
|
allow_syscall(libc::SYS_getuid),
|
||||||
allow_syscall_if(libc::SYS_ioctl, create_vmm_ioctl_seccomp_rule()?),
|
allow_syscall_if(libc::SYS_ioctl, create_vmm_ioctl_seccomp_rule()?),
|
||||||
|
allow_syscall(SYS_IO_URING_ENTER),
|
||||||
|
allow_syscall(SYS_IO_URING_SETUP),
|
||||||
|
allow_syscall(SYS_IO_URING_REGISTER),
|
||||||
allow_syscall(libc::SYS_listen),
|
allow_syscall(libc::SYS_listen),
|
||||||
allow_syscall(libc::SYS_lseek),
|
allow_syscall(libc::SYS_lseek),
|
||||||
allow_syscall(libc::SYS_madvise),
|
allow_syscall(libc::SYS_madvise),
|
||||||
|
Loading…
Reference in New Issue
Block a user