From 8f0bf8264895870e7f60e27e316a45a1035d2559 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 3 Aug 2020 08:32:28 +0200 Subject: [PATCH] io_uring: Add new feature gate By adding a new io_uring feature gate, we let the user the possibility to choose if he wants to enable the io_uring improvements or not. Since the io_uring feature depends on the availability on recent host kernels, it's better if we leave it off for now. As soon as our CI will have support for a kernel 5.6 with all the features needed from io_uring, we'll enable this feature gate permanently. Signed-off-by: Sebastien Boeuf --- Cargo.toml | 1 + block_util/Cargo.toml | 4 ++ block_util/src/lib.rs | 5 +++ virtio-devices/Cargo.toml | 1 + virtio-devices/src/lib.rs | 2 + vmm/Cargo.toml | 1 + vmm/src/device_manager.rs | 77 +++++++++++++++++++++++++++------------ 7 files changed, 67 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 858091db1..5014e0ca2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ mmio = ["vmm/mmio_support"] cmos = ["vmm/cmos"] fwdebug = ["vmm/fwdebug"] kvm = ["vmm/kvm"] +io_uring = ["vmm/io_uring"] # Integration tests require a special environment to run in integration_tests = [] diff --git a/block_util/Cargo.toml b/block_util/Cargo.toml index 165eb40e3..cc90c630b 100644 --- a/block_util/Cargo.toml +++ b/block_util/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" authors = ["The Cloud Hypervisor Authors"] edition = "2018" +[features] +default = [] +io_uring = [] + [dependencies] io-uring = { git = "https://github.com/tokio-rs/io-uring.git", branch = "0.4" } libc = "0.2.74" diff --git a/block_util/src/lib.rs b/block_util/src/lib.rs index d7d12cc40..8335d16a2 100644 --- a/block_util/src/lib.rs +++ b/block_util/src/lib.rs @@ -13,17 +13,20 @@ extern crate log; #[macro_use] extern crate serde_derive; +#[cfg(feature = "io_uring")] use io_uring::{opcode, IoUring, Probe}; use serde::ser::{Serialize, SerializeStruct, Serializer}; use std::cmp; use std::io::{self, Read, Seek, SeekFrom, Write}; use std::os::linux::fs::MetadataExt; +#[cfg(feature = "io_uring")] use std::os::unix::io::{AsRawFd, RawFd}; use std::path::PathBuf; use std::result; use virtio_bindings::bindings::virtio_blk::*; use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap}; use vm_virtio::DescriptorChain; +#[cfg(feature = "io_uring")] use vmm_sys_util::eventfd::EventFd; const SECTOR_SHIFT: u8 = 9; @@ -263,6 +266,7 @@ impl Request { Ok(0) } + #[cfg(feature = "io_uring")] pub fn execute_io_uring( &self, mem: &GuestMemoryMmap, @@ -473,6 +477,7 @@ unsafe impl ByteValued for VirtioBlockGeometry {} /// Check if io_uring for block device can be used on the current system, as /// it correctly supports the expected io_uring features. +#[cfg(feature = "io_uring")] pub fn block_io_uring_is_supported() -> bool { let error_msg = "io_uring not supported:"; diff --git a/virtio-devices/Cargo.toml b/virtio-devices/Cargo.toml index 6659f5db9..aee40f879 100644 --- a/virtio-devices/Cargo.toml +++ b/virtio-devices/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" default = [] pci_support = ["pci"] mmio_support = [] +io_uring = ["block_util/io_uring"] [dependencies] anyhow = "1.0" diff --git a/virtio-devices/src/lib.rs b/virtio-devices/src/lib.rs index b2a067a8e..5eeeafec7 100644 --- a/virtio-devices/src/lib.rs +++ b/virtio-devices/src/lib.rs @@ -31,6 +31,7 @@ use std::io; mod device; pub mod balloon; pub mod block; +#[cfg(feature = "io_uring")] pub mod block_io_uring; mod console; pub mod epoll_helper; @@ -46,6 +47,7 @@ pub mod vsock; pub use self::balloon::*; pub use self::block::*; +#[cfg(feature = "io_uring")] pub use self::block_io_uring::*; pub use self::console::*; pub use self::device::*; diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index 98bed7117..00bfc77a7 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -12,6 +12,7 @@ mmio_support = ["virtio-devices/mmio_support"] cmos = ["devices/cmos"] fwdebug = ["devices/fwdebug"] kvm = ["hypervisor/kvm"] +io_uring = ["virtio-devices/io_uring"] [dependencies] arc-swap = ">=0.4.4" diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 3838657aa..3e41d67b1 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -32,6 +32,7 @@ use arch::layout; use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START}; #[cfg(target_arch = "aarch64")] use arch::DeviceType; +#[cfg(feature = "io_uring")] use block_util::block_io_uring_is_supported; #[cfg(target_arch = "aarch64")] use devices::gic; @@ -1669,31 +1670,59 @@ impl DeviceManager { .map_err(DeviceManagerError::DetectImageType)?; let (virtio_device, migratable_device) = match image_type { ImageType::Raw => { - // Use asynchronous backend relying on io_uring if the - // syscalls are supported. - if block_io_uring_is_supported() { - let dev = Arc::new(Mutex::new( - virtio_devices::BlockIoUring::new( - id.clone(), - image, - 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)?, - )); + #[cfg(feature = "io_uring")] + { + // Use asynchronous backend relying on io_uring if the + // syscalls are supported. + if block_io_uring_is_supported() { + let dev = Arc::new(Mutex::new( + virtio_devices::BlockIoUring::new( + id.clone(), + image, + 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)?, + )); - ( - Arc::clone(&dev) as VirtioDeviceArc, - dev as Arc>, - ) - } else { + ( + Arc::clone(&dev) as VirtioDeviceArc, + dev as Arc>, + ) + } 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)?, + )); + + ( + Arc::clone(&dev) as VirtioDeviceArc, + dev as Arc>, + ) + } + } + + #[cfg(not(feature = "io_uring"))] + { let dev = Arc::new(Mutex::new( virtio_devices::Block::new( id.clone(),