diff options
author | Ivan Ren <renyime@gmail.com> | 2019-06-25 21:18:18 +0800 |
---|---|---|
committer | Juan Quintela <quintela@redhat.com> | 2019-07-24 14:47:02 +0200 |
commit | a3ec6b7d236593a95a197c229a1b673995105175 (patch) | |
tree | 831402d0a0edf71dbd7f485dd90567d3dffaddee /migration/ram.c | |
parent | 713f762a316348b00f5a3713b5314c88ab0a5852 (diff) | |
download | qemu-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/ram.c')
-rw-r--r-- | migration/ram.c | 16 |
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); |