From 1ef6996207377973bfcb86e8e5fcfbe7d4c489e0 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Fri, 14 Feb 2020 06:27:47 -0500 Subject: [PATCH] vhost_user_backend: Add helpers for EVENT_IDX Add helpers to Vring and VhostUserSlaveReqHandler for EVENT_IDX, so consumers of this crate can make use of this feature. Signed-off-by: Sergio Lopez --- Cargo.lock | 1 + src/bin/vhost_user_fs.rs | 2 ++ vhost_user_backend/Cargo.toml | 2 +- vhost_user_backend/src/lib.rs | 52 ++++++++++++++++++++++++++++++++--- vhost_user_block/src/lib.rs | 2 ++ vhost_user_net/src/lib.rs | 2 ++ 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 455cc15f2..d0814332f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1045,6 +1045,7 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "vhost_rs 0.1.0", + "virtio-bindings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)", "vm-virtio 0.1.0", "vmm-sys-util 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/bin/vhost_user_fs.rs b/src/bin/vhost_user_fs.rs index 947e66ad2..4357c8bd0 100644 --- a/src/bin/vhost_user_fs.rs +++ b/src/bin/vhost_user_fs.rs @@ -145,6 +145,8 @@ impl VhostUserBackend for VhostUserFsBack VhostUserProtocolFeatures::all() } + fn set_event_idx(&mut self, _enabled: bool) {} + fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> { self.mem = Some(mem); Ok(()) diff --git a/vhost_user_backend/Cargo.toml b/vhost_user_backend/Cargo.toml index 666f583d9..5a9ae5157 100644 --- a/vhost_user_backend/Cargo.toml +++ b/vhost_user_backend/Cargo.toml @@ -13,6 +13,7 @@ mmio_support = ["vm-virtio/mmio_support"] epoll = ">=4.0.1" libc = "0.2.66" log = "0.4.8" +virtio-bindings = "0.1.0" vm-memory = { git = "https://github.com/rust-vmm/vm-memory" } vm-virtio = { path = "../vm-virtio" } vmm-sys-util = ">=0.3.1" @@ -20,4 +21,3 @@ vmm-sys-util = ">=0.3.1" [dependencies.vhost_rs] path = "../vhost_rs" features = ["vhost-user-slave"] - diff --git a/vhost_user_backend/src/lib.rs b/vhost_user_backend/src/lib.rs index 7df006939..0e94da572 100644 --- a/vhost_user_backend/src/lib.rs +++ b/vhost_user_backend/src/lib.rs @@ -23,6 +23,7 @@ use vhost_rs::vhost_user::{ Error as VhostUserError, Result as VhostUserResult, SlaveFsCacheReq, SlaveListener, VhostUserSlaveReqHandler, }; +use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use vm_memory::guest_memory::FileOffset; use vm_memory::{GuestAddress, GuestMemoryMmap}; use vm_virtio::Queue; @@ -69,6 +70,9 @@ pub trait VhostUserBackend: Send + Sync + 'static { /// Virtio protocol features. fn protocol_features(&self) -> VhostUserProtocolFeatures; + /// Tell the backend if EVENT_IDX has been negotiated. + fn set_event_idx(&mut self, enabled: bool); + /// Update guest memory regions. fn update_memory(&mut self, mem: GuestMemoryMmap) -> result::Result<(), io::Error>; @@ -200,6 +204,8 @@ pub struct Vring { call: Option, err: Option, enabled: bool, + event_idx: bool, + signalled_used: Option>, } impl Vring { @@ -210,6 +216,8 @@ impl Vring { call: None, err: None, enabled: false, + event_idx: false, + signalled_used: None, } } @@ -217,12 +225,41 @@ impl Vring { &mut self.queue } - pub fn signal_used_queue(&self) -> result::Result<(), io::Error> { - if let Some(call) = self.call.as_ref() { - return call.write(1); + pub fn set_event_idx(&mut self, enabled: bool) { + /* Also reset the last signalled event */ + self.signalled_used = None; + self.event_idx = enabled; + } + + pub fn needs_notification( + &mut self, + used_idx: Wrapping, + used_event: Option>, + ) -> bool { + if !self.event_idx { + return true; } - Ok(()) + let mut notify = true; + + if let Some(old_idx) = self.signalled_used { + if let Some(used_event) = used_event { + if (used_idx - used_event - Wrapping(1u16)) >= (used_idx - old_idx) { + notify = false; + } + } + } + + self.signalled_used = Some(used_idx); + notify + } + + pub fn signal_used_queue(&mut self) -> result::Result<(), io::Error> { + if let Some(call) = self.call.as_ref() { + call.write(1) + } else { + Ok(()) + } } } @@ -660,6 +697,13 @@ impl VhostUserSlaveReqHandler for VhostUserHandler { .queue .next_avail = Wrapping(base as u16); self.vrings[index as usize].write().unwrap().queue.next_used = Wrapping(base as u16); + + let event_idx: bool = (self.acked_features & (1 << VIRTIO_RING_F_EVENT_IDX)) != 0; + self.vrings[index as usize] + .write() + .unwrap() + .set_event_idx(event_idx); + self.backend.write().unwrap().set_event_idx(event_idx); Ok(()) } diff --git a/vhost_user_block/src/lib.rs b/vhost_user_block/src/lib.rs index 619edce25..448b59714 100644 --- a/vhost_user_block/src/lib.rs +++ b/vhost_user_block/src/lib.rs @@ -212,6 +212,8 @@ impl VhostUserBackend for VhostUserBlkBackend { VhostUserProtocolFeatures::CONFIG } + fn set_event_idx(&mut self, _enabled: bool) {} + fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> { self.mem = Some(mem); Ok(()) diff --git a/vhost_user_net/src/lib.rs b/vhost_user_net/src/lib.rs index d2d588e2d..a87b49917 100644 --- a/vhost_user_net/src/lib.rs +++ b/vhost_user_net/src/lib.rs @@ -275,6 +275,8 @@ impl VhostUserBackend for VhostUserNetBackend { VhostUserProtocolFeatures::all() } + fn set_event_idx(&mut self, _enabled: bool) {} + fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> { self.mem = Some(mem); Ok(())