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 <slp@redhat.com>
This commit is contained in:
Sergio Lopez
2020-02-14 06:27:47 -05:00
committed by Rob Bradford
parent d17fa784bc
commit 1ef6996207
6 changed files with 56 additions and 5 deletions
Generated
+1
View File
@@ -1045,6 +1045,7 @@ dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"vhost_rs 0.1.0", "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-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)",
"vm-virtio 0.1.0", "vm-virtio 0.1.0",
"vmm-sys-util 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "vmm-sys-util 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+2
View File
@@ -145,6 +145,8 @@ impl<F: FileSystem + Send + Sync + 'static> VhostUserBackend for VhostUserFsBack
VhostUserProtocolFeatures::all() VhostUserProtocolFeatures::all()
} }
fn set_event_idx(&mut self, _enabled: bool) {}
fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> { fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> {
self.mem = Some(mem); self.mem = Some(mem);
Ok(()) Ok(())
+1 -1
View File
@@ -13,6 +13,7 @@ mmio_support = ["vm-virtio/mmio_support"]
epoll = ">=4.0.1" epoll = ">=4.0.1"
libc = "0.2.66" libc = "0.2.66"
log = "0.4.8" log = "0.4.8"
virtio-bindings = "0.1.0"
vm-memory = { git = "https://github.com/rust-vmm/vm-memory" } vm-memory = { git = "https://github.com/rust-vmm/vm-memory" }
vm-virtio = { path = "../vm-virtio" } vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = ">=0.3.1" vmm-sys-util = ">=0.3.1"
@@ -20,4 +21,3 @@ vmm-sys-util = ">=0.3.1"
[dependencies.vhost_rs] [dependencies.vhost_rs]
path = "../vhost_rs" path = "../vhost_rs"
features = ["vhost-user-slave"] features = ["vhost-user-slave"]
+48 -4
View File
@@ -23,6 +23,7 @@ use vhost_rs::vhost_user::{
Error as VhostUserError, Result as VhostUserResult, SlaveFsCacheReq, SlaveListener, Error as VhostUserError, Result as VhostUserResult, SlaveFsCacheReq, SlaveListener,
VhostUserSlaveReqHandler, VhostUserSlaveReqHandler,
}; };
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use vm_memory::guest_memory::FileOffset; use vm_memory::guest_memory::FileOffset;
use vm_memory::{GuestAddress, GuestMemoryMmap}; use vm_memory::{GuestAddress, GuestMemoryMmap};
use vm_virtio::Queue; use vm_virtio::Queue;
@@ -69,6 +70,9 @@ pub trait VhostUserBackend: Send + Sync + 'static {
/// Virtio protocol features. /// Virtio protocol features.
fn protocol_features(&self) -> VhostUserProtocolFeatures; 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. /// Update guest memory regions.
fn update_memory(&mut self, mem: GuestMemoryMmap) -> result::Result<(), io::Error>; fn update_memory(&mut self, mem: GuestMemoryMmap) -> result::Result<(), io::Error>;
@@ -200,6 +204,8 @@ pub struct Vring {
call: Option<EventFd>, call: Option<EventFd>,
err: Option<EventFd>, err: Option<EventFd>,
enabled: bool, enabled: bool,
event_idx: bool,
signalled_used: Option<Wrapping<u16>>,
} }
impl Vring { impl Vring {
@@ -210,6 +216,8 @@ impl Vring {
call: None, call: None,
err: None, err: None,
enabled: false, enabled: false,
event_idx: false,
signalled_used: None,
} }
} }
@@ -217,12 +225,41 @@ impl Vring {
&mut self.queue &mut self.queue
} }
pub fn signal_used_queue(&self) -> result::Result<(), io::Error> { pub fn set_event_idx(&mut self, enabled: bool) {
if let Some(call) = self.call.as_ref() { /* Also reset the last signalled event */
return call.write(1); self.signalled_used = None;
self.event_idx = enabled;
}
pub fn needs_notification(
&mut self,
used_idx: Wrapping<u16>,
used_event: Option<Wrapping<u16>>,
) -> 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<S: VhostUserBackend> VhostUserSlaveReqHandler for VhostUserHandler<S> {
.queue .queue
.next_avail = Wrapping(base as u16); .next_avail = Wrapping(base as u16);
self.vrings[index as usize].write().unwrap().queue.next_used = 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(()) Ok(())
} }
+2
View File
@@ -212,6 +212,8 @@ impl VhostUserBackend for VhostUserBlkBackend {
VhostUserProtocolFeatures::CONFIG VhostUserProtocolFeatures::CONFIG
} }
fn set_event_idx(&mut self, _enabled: bool) {}
fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> { fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> {
self.mem = Some(mem); self.mem = Some(mem);
Ok(()) Ok(())
+2
View File
@@ -275,6 +275,8 @@ impl VhostUserBackend for VhostUserNetBackend {
VhostUserProtocolFeatures::all() VhostUserProtocolFeatures::all()
} }
fn set_event_idx(&mut self, _enabled: bool) {}
fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> { fn update_memory(&mut self, mem: GuestMemoryMmap) -> VhostUserBackendResult<()> {
self.mem = Some(mem); self.mem = Some(mem);
Ok(()) Ok(())