aboutsummaryrefslogtreecommitdiff
path: root/migration
diff options
context:
space:
mode:
authorIvan Ren <renyime@gmail.com>2019-06-25 21:18:18 +0800
committerJuan Quintela <quintela@redhat.com>2019-07-24 14:47:02 +0200
commita3ec6b7d236593a95a197c229a1b673995105175 (patch)
tree831402d0a0edf71dbd7f485dd90567d3dffaddee /migration
parent713f762a316348b00f5a3713b5314c88ab0a5852 (diff)
downloadqemu-a3ec6b7d236593a95a197c229a1b673995105175.zip
qemu-a3ec6b7d236593a95a197c229a1b673995105175.tar.gz
qemu-a3ec6b7d236593a95a197c229a1b673995105175.tar.bz2
migration: fix migrate_cancel leads live_migration thread hung forever
When we 'migrate_cancel' a multifd migration, live_migration thread may hung forever at some points, because of multifd_send_thread has already exit for socket error: 1. multifd_send_pages may hung at qemu_sem_wait(&multifd_send_state-> channels_ready) 2. multifd_send_sync_main my hung at qemu_sem_wait(&multifd_send_state-> sem_sync) Signed-off-by: Ivan Ren <ivanren@tencent.com> Message-Id: <1561468699-9819-3-git-send-email-ivanren@tencent.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com> --- Remove spurious not needed bits
Diffstat (limited to 'migration')
-rw-r--r--migration/ram.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/migration/ram.c b/migration/ram.c
index 52a2d49..87bb7da 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1097,7 +1097,8 @@ static void *multifd_send_thread(void *opaque)
{
MultiFDSendParams *p = opaque;
Error *local_err = NULL;
- int ret;
+ int ret = 0;
+ uint32_t flags = 0;
trace_multifd_send_thread_start(p->id);
rcu_register_thread();
@@ -1115,7 +1116,7 @@ static void *multifd_send_thread(void *opaque)
if (p->pending_job) {
uint32_t used = p->pages->used;
uint64_t packet_num = p->packet_num;
- uint32_t flags = p->flags;
+ flags = p->flags;
p->next_packet_size = used * qemu_target_page_size();
multifd_send_fill_packet(p);
@@ -1164,6 +1165,17 @@ out:
multifd_send_terminate_threads(local_err);
}
+ /*
+ * Error happen, I will exit, but I can't just leave, tell
+ * who pay attention to me.
+ */
+ if (ret != 0) {
+ if (flags & MULTIFD_FLAG_SYNC) {
+ qemu_sem_post(&multifd_send_state->sem_sync);
+ }
+ qemu_sem_post(&multifd_send_state->channels_ready);
+ }
+
qemu_mutex_lock(&p->mutex);
p->running = false;
qemu_mutex_unlock(&p->mutex);