Snap for 13278158 from 9c31a4bdb0efeac6dcfe51fcbf16bf4594903ed7 to sdk-release
Change-Id: Icebbfb77d32ac64e46d4b0f411febfc085c57d3e
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 51d3f04..c169b0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
### Changed
### Fixed
+- [#800](https://github.com/rust-vmm/vhost-device/pull/800) Disable EPOLLOUT if triggered while txbuf is empty
### Deprecated
diff --git a/src/vhu_vsock_thread.rs b/src/vhu_vsock_thread.rs
index 5cce0a8..24dd1cb 100644
--- a/src/vhu_vsock_thread.rs
+++ b/src/vhu_vsock_thread.rs
@@ -17,7 +17,7 @@
thread,
};
-use log::warn;
+use log::{error, warn};
use vhost_user_backend::{VringEpollHandler, VringRwLock, VringT};
use virtio_queue::QueueOwnedT;
use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};
@@ -377,6 +377,9 @@
.unwrap();
} else {
// Previously connected connection
+
+ // Get epoll fd before getting conn as that takes self mut ref
+ let epoll_fd = self.get_epoll_fd();
let key = self.thread_backend.listener_map.get(&fd).unwrap();
let conn = self.thread_backend.conn_map.get_mut(key).unwrap();
@@ -387,6 +390,12 @@
if cnt > 0 {
conn.fwd_cnt += Wrapping(cnt as u32);
conn.rx_queue.enqueue(RxOps::CreditUpdate);
+ } else {
+ // If no remaining data to flush, try to disable EPOLLOUT
+ if Self::epoll_modify(epoll_fd, fd, epoll::Events::EPOLLIN).is_err()
+ {
+ error!("Failed to disable EPOLLOUT");
+ }
}
self.thread_backend
.backend_rxq
diff --git a/src/vsock_conn.rs b/src/vsock_conn.rs
index 0a766df..868200c 100644
--- a/src/vsock_conn.rs
+++ b/src/vsock_conn.rs
@@ -340,6 +340,16 @@
}
if written_count != buf.len() {
+ // Try to re-enable EPOLLOUT in case it is disabled when txbuf is empty.
+ if VhostUserVsockThread::epoll_modify(
+ self.epoll_fd,
+ self.stream.as_raw_fd(),
+ epoll::Events::EPOLLIN | epoll::Events::EPOLLOUT,
+ )
+ .is_err()
+ {
+ error!("Failed to re-enable EPOLLOUT");
+ }
return self.tx_buf.push(&buf.offset(written_count).unwrap());
}