mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-21 19:02:30 +00:00
virtio-devices: vhost_user: Support inflight I/O tracking
Vhost user INFLIGHT_SHMFD protocol feature supports inflight I/O tracking, this commit implement the vhost-user device (master) support of the feature. Till this commit, specific vhost-user devices (blk, fs, or net) have not enable this feature. Signed-off-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
This commit is contained in:
parent
f060ecd705
commit
bfd4aa2fed
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1111,7 +1111,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "vhost"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rust-vmm/vhost?branch=master#30ba3e7bbe9e0542cf480f44bc6845a8dbd2a6ba"
|
||||
source = "git+https://github.com/rust-vmm/vhost?branch=master#a8ff939161d41fc2f449b80e461d013c1e19f666"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
2
fuzz/Cargo.lock
generated
2
fuzz/Cargo.lock
generated
@ -652,7 +652,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "vhost"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rust-vmm/vhost?branch=master#e5b930b73a47cbdd79858e2e68bcb57123d1c1f3"
|
||||
source = "git+https://github.com/rust-vmm/vhost?branch=master#a8ff939161d41fc2f449b80e461d013c1e19f666"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -959,6 +959,24 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandlerMut for VhostUserHandler<S> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_inflight_fd(
|
||||
&mut self,
|
||||
_: &vhost::vhost_user::message::VhostUserInflight,
|
||||
) -> std::result::Result<
|
||||
(vhost::vhost_user::message::VhostUserInflight, i32),
|
||||
vhost::vhost_user::Error,
|
||||
> {
|
||||
std::unimplemented!()
|
||||
}
|
||||
|
||||
fn set_inflight_fd(
|
||||
&mut self,
|
||||
_: &vhost::vhost_user::message::VhostUserInflight,
|
||||
_: std::fs::File,
|
||||
) -> std::result::Result<(), vhost::vhost_user::Error> {
|
||||
std::unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: VhostUserBackend> Drop for VhostUserHandler<S> {
|
||||
|
@ -231,6 +231,7 @@ impl VirtioDevice for Blk {
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
&slave_req_handler,
|
||||
None,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserBlkSetup)?;
|
||||
|
||||
@ -251,6 +252,7 @@ impl VirtioDevice for Blk {
|
||||
socket_path: self.socket_path.clone(),
|
||||
server: false,
|
||||
slave_req_handler: None,
|
||||
inflight: None,
|
||||
};
|
||||
|
||||
let paused = self.common.paused.clone();
|
||||
|
@ -452,6 +452,7 @@ impl VirtioDevice for Fs {
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
&slave_req_handler,
|
||||
None,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserFsSetup)?;
|
||||
|
||||
@ -471,6 +472,7 @@ impl VirtioDevice for Fs {
|
||||
socket_path: self.socket_path.clone(),
|
||||
server: false,
|
||||
slave_req_handler,
|
||||
inflight: None,
|
||||
};
|
||||
|
||||
let paused = self.common.paused.clone();
|
||||
|
@ -11,7 +11,7 @@ use std::io;
|
||||
use std::ops::Deref;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::sync::{atomic::AtomicBool, Arc, Barrier, Mutex};
|
||||
use vhost::vhost_user::message::VhostUserVirtioFeatures;
|
||||
use vhost::vhost_user::message::{VhostUserInflight, VhostUserVirtioFeatures};
|
||||
use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMasterReqHandler};
|
||||
use vhost::Error as VhostError;
|
||||
use vm_memory::{Error as MmapError, GuestAddressSpace, GuestMemoryAtomic};
|
||||
@ -103,6 +103,10 @@ pub enum Error {
|
||||
VhostUserGetConfig(VhostError),
|
||||
/// Failed setting the configuration.
|
||||
VhostUserSetConfig(VhostError),
|
||||
/// Failed getting inflight shm log.
|
||||
VhostUserGetInflight(VhostError),
|
||||
/// Failed setting inflight shm log.
|
||||
VhostUserSetInflight(VhostError),
|
||||
/// Invalid used address.
|
||||
UsedAddress,
|
||||
/// Invalid features provided from vhost-user backend
|
||||
@ -128,6 +132,12 @@ pub const DEFAULT_VIRTIO_FEATURES: u64 = 1 << VIRTIO_F_RING_INDIRECT_DESC
|
||||
const HUP_CONNECTION_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1;
|
||||
const SLAVE_REQ_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 2;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Inflight {
|
||||
pub info: VhostUserInflight,
|
||||
pub fd: Option<std::fs::File>,
|
||||
}
|
||||
|
||||
pub struct VhostUserEpollHandler<S: VhostUserMasterReqHandler> {
|
||||
pub vu: Arc<Mutex<Master>>,
|
||||
pub mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
@ -141,6 +151,7 @@ pub struct VhostUserEpollHandler<S: VhostUserMasterReqHandler> {
|
||||
pub socket_path: String,
|
||||
pub server: bool,
|
||||
pub slave_req_handler: Option<MasterReqHandler<S>>,
|
||||
pub inflight: Option<Inflight>,
|
||||
}
|
||||
|
||||
impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
|
||||
@ -198,6 +209,7 @@ impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
|
||||
self.acked_features,
|
||||
self.acked_protocol_features,
|
||||
&self.slave_req_handler,
|
||||
self.inflight.as_mut(),
|
||||
)
|
||||
.map_err(|e| {
|
||||
EpollHelperError::IoError(std::io::Error::new(
|
||||
|
@ -300,6 +300,7 @@ impl VirtioDevice for Net {
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
&slave_req_handler,
|
||||
None,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserNetSetup)?;
|
||||
|
||||
@ -320,6 +321,7 @@ impl VirtioDevice for Net {
|
||||
socket_path: self.socket_path.clone(),
|
||||
server: self.server,
|
||||
slave_req_handler: None,
|
||||
inflight: None,
|
||||
};
|
||||
|
||||
let paused = self.common.paused.clone();
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
use super::super::{Descriptor, Queue};
|
||||
use super::{Error, Result};
|
||||
use crate::vhost_user::Inflight;
|
||||
use crate::{get_host_address_range, VirtioInterrupt, VirtioInterruptType};
|
||||
use crate::{GuestMemoryMmap, GuestRegionMmap};
|
||||
use std::convert::TryInto;
|
||||
@ -12,7 +13,9 @@ use std::sync::Arc;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::vec::Vec;
|
||||
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
|
||||
use vhost::vhost_user::message::{
|
||||
VhostUserInflight, VhostUserProtocolFeatures, VhostUserVirtioFeatures,
|
||||
};
|
||||
use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler};
|
||||
use vhost::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData};
|
||||
use vm_memory::{Address, Error as MmapError, GuestMemory, GuestMemoryRegion};
|
||||
@ -100,6 +103,7 @@ pub fn negotiate_features_vhost_user(
|
||||
Ok((acked_features, acked_protocol_features))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
vu: &mut Master,
|
||||
mem: &GuestMemoryMmap,
|
||||
@ -108,6 +112,7 @@ pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
||||
acked_features: u64,
|
||||
slave_req_handler: &Option<MasterReqHandler<S>>,
|
||||
inflight: Option<&mut Inflight>,
|
||||
) -> Result<()> {
|
||||
vu.set_features(acked_features)
|
||||
.map_err(Error::VhostUserSetFeatures)?;
|
||||
@ -115,6 +120,26 @@ pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
// Let's first provide the memory table to the backend.
|
||||
update_mem_table(vu, mem)?;
|
||||
|
||||
// Setup for inflight I/O tracking shared memory.
|
||||
if let Some(inflight) = inflight {
|
||||
if inflight.fd.is_none() {
|
||||
let inflight_req_info = VhostUserInflight {
|
||||
mmap_size: 0,
|
||||
mmap_offset: 0,
|
||||
num_queues: queues.len() as u16,
|
||||
queue_size: queues[0].actual_size(),
|
||||
};
|
||||
let (info, fd) = vu
|
||||
.get_inflight_fd(&inflight_req_info)
|
||||
.map_err(Error::VhostUserGetInflight)?;
|
||||
inflight.info = info;
|
||||
inflight.fd = Some(fd);
|
||||
}
|
||||
// Unwrapping the inflight fd is safe here since we know it can't be None.
|
||||
vu.set_inflight_fd(&inflight.info, inflight.fd.as_ref().unwrap().as_raw_fd())
|
||||
.map_err(Error::VhostUserSetInflight)?;
|
||||
}
|
||||
|
||||
for (queue_index, queue) in queues.into_iter().enumerate() {
|
||||
let actual_size: usize = queue.actual_size().try_into().unwrap();
|
||||
|
||||
@ -194,6 +219,7 @@ pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
acked_features: u64,
|
||||
acked_protocol_features: u64,
|
||||
slave_req_handler: &Option<MasterReqHandler<S>>,
|
||||
inflight: Option<&mut Inflight>,
|
||||
) -> Result<()> {
|
||||
vu.set_owner().map_err(Error::VhostUserSetOwner)?;
|
||||
vu.get_features().map_err(Error::VhostUserGetFeatures)?;
|
||||
@ -215,6 +241,7 @@ pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
virtio_interrupt,
|
||||
acked_features,
|
||||
slave_req_handler,
|
||||
inflight,
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user