summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Boeuf <sebastien.boeuf@intel.com>2021-03-08 12:00:31 +0100
committerJiang Liu <gerry@linux.alibaba.com>2021-03-10 23:37:29 +0800
commite7d46d6980ed1312e16243ff2ec4bb018f9aec5f (patch)
tree36bd2804a6c6cc8838e4050fe28ce1a15631c845
parent0bfb5a3180dbff2b29ec1fe8af4ed4dbec99a7db (diff)
downloadvmm_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.rs5
-rw-r--r--src/vhost_user/master.rs16
-rw-r--r--src/vhost_user/mod.rs6
-rw-r--r--src/vhost_user/slave_req_handler.rs18
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);
}