mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-25 09:21:15 +00:00
vm-virtio: Consume pause events to prevent infinite epoll_wait calls
When a virtio device is paused an event is written to the appropriate "pause" EventFd for the device. This will be noticed by the the device's epoll_wait(), an atomic bool checked an if true then the thread is parked(). When resuming the bool is reset and the thread is unpark()ed. However the event triggering the pause is still in the EventFd so the epoll_wait() will continue to return but because the boolean is not set the thread will not be park()ed but instead we will busy loop around an event that is not being consumed. The solution is to drain the "pause" EventFd when the event is first received and thus the epoll_wait() will only return for the pause event once. This resolves the infinite epoll_wait() wake-ups. Fixes: #869 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
16fd506bb8
commit
30b69549e1
@ -745,6 +745,8 @@ impl<T: DiskFile> BlockEpollHandler<T> {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-block epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-block epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -275,6 +275,8 @@ impl ConsoleEpollHandler {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-console epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-console epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -729,6 +729,8 @@ impl IommuEpollHandler {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-iommu epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-iommu epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -272,6 +272,8 @@ impl NetEpollHandler {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-net epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-net epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -269,6 +269,8 @@ impl NetCtrlEpollHandler {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing vhost-user epoll loop");
|
debug!("PAUSE_EVENT received, pausing vhost-user epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -290,6 +290,8 @@ impl PmemEpollHandler {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-pmem epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-pmem epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -155,6 +155,8 @@ impl RngEpollHandler {
|
|||||||
break 'epoll;
|
break 'epoll;
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-rng epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-rng epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -153,6 +153,8 @@ impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
|
|||||||
break 'poll;
|
break 'poll;
|
||||||
}
|
}
|
||||||
x if pause_evt_index == x => {
|
x if pause_evt_index == x => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.vu_epoll_cfg.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing vhost-user epoll loop");
|
debug!("PAUSE_EVENT received, pausing vhost-user epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
@ -351,6 +351,8 @@ where
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
PAUSE_EVENT => {
|
PAUSE_EVENT => {
|
||||||
|
// Drain pause event
|
||||||
|
let _ = self.pause_evt.read();
|
||||||
debug!("PAUSE_EVENT received, pausing virtio-vsock epoll loop");
|
debug!("PAUSE_EVENT received, pausing virtio-vsock epoll loop");
|
||||||
// We loop here to handle spurious park() returns.
|
// We loop here to handle spurious park() returns.
|
||||||
// Until we have not resumed, the paused boolean will
|
// Until we have not resumed, the paused boolean will
|
||||||
|
Loading…
Reference in New Issue
Block a user