>From abbe3b57af6a28bb81e5fb8b09b10802a8ccc3fe Mon Sep 17 00:00:00 2001 From: Dor Laor <dor@xxxxxxxxxx> Date: Wed, 15 Jul 2009 17:53:16 +0300 Subject: [PATCH] Fix migration issue when the destination is loaded If the migration socket is full, we get EAGAIN for the write. The set_fd_handler2 defers the write for later on. The function tries to wake up the iothread by qemu_kvm_notify_work. Since this happens in a loop, multiple times, the pipe that emulates eventfd becomes full and we get a deadlock. It is solved by checking for write-readiness using select. Note that I check for select only for full 8 byte write and not for partial writes. This is because we'll break the reader otherwise. Signed-off-by: Dor Laor <dor@xxxxxxxxxx> --- qemu-kvm.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/qemu-kvm.c b/qemu-kvm.c index ed7e466..0ea67a7 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -2094,12 +2094,28 @@ void qemu_kvm_notify_work(void) uint64_t value = 1; char buffer[8]; size_t offset = 0; + fd_set wfds; + struct timeval tv; + int retval; if (io_thread_fd == -1) return; memcpy(buffer, &value, sizeof(value)); + FD_ZERO(&wfds); + FD_SET(io_thread_fd, &wfds); + tv.tv_sec = tv.tv_usec = 0; + retval = select(io_thread_fd + 1, NULL, &wfds, NULL, &tv); + if (retval == -1) { + fprintf(stderr, "failed to notify io thread due to select error\n"); + return; + } else if (retval == 0) + /* We probably ponded this pipe too much and it is full now */ + return; + + assert(FD_ISSET(io_thread_fd, &wfds)); + while (offset < 8) { ssize_t len; -- 1.6.2.5