diff options
author | Sebastien Boeuf <sebastien.boeuf@intel.com> | 2021-03-08 12:00:31 +0100 |
---|---|---|
committer | Jiang Liu <gerry@linux.alibaba.com> | 2021-03-10 23:37:29 +0800 |
commit | e7d46d6980ed1312e16243ff2ec4bb018f9aec5f (patch) | |
tree | 36bd2804a6c6cc8838e4050fe28ce1a15631c845 | |
parent | 0bfb5a3180dbff2b29ec1fe8af4ed4dbec99a7db (diff) | |
download | vmm_vhost-e7d46d6980ed1312e16243ff2ec4bb018f9aec5f.tar.gz |
vhost_user: Add support for GET_MAX_MEM_SLOTS
Add the support for GET_MAX_MEM_SLOTS command. This requests the
vhost-user backend to provide the maximum amount of memory slots
that can be supported.
It is only available if the protocol feature
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS has been negotiated.
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
-rw-r--r-- | src/vhost_user/dummy_slave.rs | 5 | ||||
-rw-r--r-- | src/vhost_user/master.rs | 16 | ||||
-rw-r--r-- | src/vhost_user/mod.rs | 6 | ||||
-rw-r--r-- | src/vhost_user/slave_req_handler.rs | 18 |
4 files changed, 45 insertions, 0 deletions
diff --git a/src/vhost_user/dummy_slave.rs b/src/vhost_user/dummy_slave.rs index 9eedcbb..989888f 100644 --- a/src/vhost_user/dummy_slave.rs +++ b/src/vhost_user/dummy_slave.rs @@ -8,6 +8,7 @@ use super::*; pub const MAX_QUEUE_NUM: usize = 2; pub const MAX_VRING_NUM: usize = 256; +pub const MAX_MEM_SLOTS: usize = 32; pub const VIRTIO_FEATURES: u64 = 0x40000003; #[derive(Default)] @@ -243,4 +244,8 @@ impl VhostUserSlaveReqHandlerMut for DummySlaveReqHandler { } Ok(()) } + + fn get_max_mem_slots(&mut self) -> Result<u64> { + Ok(MAX_MEM_SLOTS as u64) + } } diff --git a/src/vhost_user/master.rs b/src/vhost_user/master.rs index f9da535..a721355 100644 --- a/src/vhost_user/master.rs +++ b/src/vhost_user/master.rs @@ -50,6 +50,9 @@ pub trait VhostUserMaster: VhostBackend { /// Setup slave communication channel. fn set_slave_request_fd(&mut self, fd: RawFd) -> Result<()>; + + /// Query the maximum amount of memory slots supported by the backend. + fn get_max_mem_slots(&mut self) -> Result<u64>; } fn error_code<T>(err: VhostUserError) -> Result<T> { @@ -435,6 +438,19 @@ impl VhostUserMaster for Master { node.send_request_header(MasterReq::SET_SLAVE_REQ_FD, Some(&fds))?; Ok(()) } + + fn get_max_mem_slots(&mut self) -> Result<u64> { + let mut node = self.node(); + if node.acked_protocol_features & VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS.bits() == 0 + { + return error_code(VhostUserError::InvalidOperation); + } + + let hdr = node.send_request_header(MasterReq::GET_MAX_MEM_SLOTS, None)?; + let val = node.recv_reply::<VhostUserU64>(&hdr)?; + + Ok(val.value) + } } impl AsRawFd for Master { diff --git a/src/vhost_user/mod.rs b/src/vhost_user/mod.rs index 00382f4..38b94ec 100644 --- a/src/vhost_user/mod.rs +++ b/src/vhost_user/mod.rs @@ -333,6 +333,9 @@ mod tests { slave.handle_request().unwrap(); slave.handle_request().unwrap(); + // get_max_mem_slots() + slave.handle_request().unwrap(); + sbar.wait(); }); @@ -395,6 +398,9 @@ mod tests { master.set_vring_kick(0, &eventfd).unwrap(); master.set_vring_err(0, &eventfd).unwrap(); + let max_mem_slots = master.get_max_mem_slots().unwrap(); + assert_eq!(max_mem_slots, 32); + mbar.wait(); } diff --git a/src/vhost_user/slave_req_handler.rs b/src/vhost_user/slave_req_handler.rs index 3b44e4c..870d324 100644 --- a/src/vhost_user/slave_req_handler.rs +++ b/src/vhost_user/slave_req_handler.rs @@ -62,6 +62,7 @@ pub trait VhostUserSlaveReqHandler { fn get_config(&self, offset: u32, size: u32, flags: VhostUserConfigFlags) -> Result<Vec<u8>>; fn set_config(&self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>; fn set_slave_req_fd(&self, _vu_req: SlaveFsCacheReq) {} + fn get_max_mem_slots(&self) -> Result<u64>; } /// Services provided to the master by the slave without interior mutability. @@ -102,6 +103,7 @@ pub trait VhostUserSlaveReqHandlerMut { ) -> Result<Vec<u8>>; fn set_config(&mut self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>; fn set_slave_req_fd(&mut self, _vu_req: SlaveFsCacheReq) {} + fn get_max_mem_slots(&mut self) -> Result<u64>; } impl<T: VhostUserSlaveReqHandlerMut> VhostUserSlaveReqHandler for Mutex<T> { @@ -190,6 +192,10 @@ impl<T: VhostUserSlaveReqHandlerMut> VhostUserSlaveReqHandler for Mutex<T> { fn set_slave_req_fd(&self, vu_req: SlaveFsCacheReq) { self.lock().unwrap().set_slave_req_fd(vu_req) } + + fn get_max_mem_slots(&self) -> Result<u64> { + self.lock().unwrap().get_max_mem_slots() + } } /// Server to handle service requests from masters from the master communication channel. @@ -417,6 +423,18 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { self.check_request_size(&hdr, size, hdr.get_size() as usize)?; self.set_slave_req_fd(&hdr, rfds)?; } + MasterReq::GET_MAX_MEM_SLOTS => { + if self.acked_protocol_features + & VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS.bits() + == 0 + { + return Err(Error::InvalidOperation); + } + self.check_request_size(&hdr, size, 0)?; + let num = self.backend.get_max_mem_slots()?; + let msg = VhostUserU64::new(num); + self.send_reply_message(&hdr, &msg)?; + } _ => { return Err(Error::InvalidMessage); } |