From 9756a7d427aa0bffc23b45192eaa6ecc9daedaff Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Thu, 11 Dec 2025 11:17:19 +0100 Subject: [PATCH] vhost: fix double-locking in Backend to Fronted req handlers Some methods acquire the mutex lock twice: once to check feature flags and again when calling send_message(), this is inefficient and also racy, so acquire the lock once and reuse the guard for both operations. Remove send_message() wrapper method now unused. Signed-off-by: Stefano Garzarella --- vhost/CHANGELOG.md | 1 + vhost/src/vhost_user/backend_req.rs | 40 ++++++++++++----------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/vhost/CHANGELOG.md b/vhost/CHANGELOG.md index 4867f17..f72ae24 100644 --- a/vhost/CHANGELOG.md +++ b/vhost/CHANGELOG.md @@ -8,6 +8,7 @@ ### Changed ### Deprecated ### Fixed +- [[#338]](https://github.com/rust-vmm/vhost/pull/338) vhost: fix double-locking in Backend to Frontend request handlers ## v0.15.0 diff --git a/vhost/src/vhost_user/backend_req.rs b/vhost/src/vhost_user/backend_req.rs index 02efeee..3b28bcf 100644 --- a/vhost/src/vhost_user/backend_req.rs +++ b/vhost/src/vhost_user/backend_req.rs @@ -107,19 +107,6 @@ impl Backend { } } - fn send_message( - &self, - request: BackendReq, - body: &T, - fds: Option<&[RawFd]>, - ) -> io::Result { - Ok(self - .inner - .lock() - .unwrap() - .send_message(request, body, fds)?) - } - /// Create a new instance from a `UnixStream` object. pub fn from_stream(sock: UnixStream) -> Self { Self::new(Endpoint::>::from_stream( @@ -161,18 +148,20 @@ impl Backend { impl VhostUserFrontendReqHandler for Backend { /// Forward vhost-user shared-object add request to the frontend. fn shared_object_add(&self, uuid: &VhostUserSharedMsg) -> HandlerResult { - if !self.inner.lock().unwrap().shared_object_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shared_object_negotiated { return Err(io::Error::other("Shared Object feature not negotiated")); } - self.send_message(BackendReq::SHARED_OBJECT_ADD, uuid, None) + Ok(guard.send_message(BackendReq::SHARED_OBJECT_ADD, uuid, None)?) } /// Forward vhost-user shared-object remove request to the frontend. fn shared_object_remove(&self, uuid: &VhostUserSharedMsg) -> HandlerResult { - if !self.inner.lock().unwrap().shared_object_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shared_object_negotiated { return Err(io::Error::other("Shared Object feature not negotiated")); } - self.send_message(BackendReq::SHARED_OBJECT_REMOVE, uuid, None) + Ok(guard.send_message(BackendReq::SHARED_OBJECT_REMOVE, uuid, None)?) } /// Forward vhost-user shared-object lookup request to the frontend. @@ -181,30 +170,33 @@ impl VhostUserFrontendReqHandler for Backend { uuid: &VhostUserSharedMsg, fd: &dyn AsRawFd, ) -> HandlerResult { - if !self.inner.lock().unwrap().shared_object_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shared_object_negotiated { return Err(io::Error::other("Shared Object feature not negotiated")); } - self.send_message( + Ok(guard.send_message( BackendReq::SHARED_OBJECT_LOOKUP, uuid, Some(&[fd.as_raw_fd()]), - ) + )?) } /// Forward vhost-user memory map file request to the frontend. fn shmem_map(&self, req: &VhostUserMMap, fd: &dyn AsRawFd) -> HandlerResult { - if !self.inner.lock().unwrap().shmem_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shmem_negotiated { return Err(io::Error::other("SHMEM feature not negotiated")); } - self.send_message(BackendReq::SHMEM_MAP, req, Some(&[fd.as_raw_fd()])) + Ok(guard.send_message(BackendReq::SHMEM_MAP, req, Some(&[fd.as_raw_fd()]))?) } /// Forward vhost-user memory unmap file request to the frontend. fn shmem_unmap(&self, req: &VhostUserMMap) -> HandlerResult { - if !self.inner.lock().unwrap().shmem_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shmem_negotiated { return Err(io::Error::other("SHMEM feature not negotiated")); } - self.send_message(BackendReq::SHMEM_UNMAP, req, None) + Ok(guard.send_message(BackendReq::SHMEM_UNMAP, req, None)?) } }