From patchwork Mon Mar 25 13:54:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fei Li X-Patchwork-Id: 1064385 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Fdw3obbc"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44SbfK0Tt9z9sSp for ; Tue, 26 Mar 2019 01:06:31 +1100 (AEDT) Received: from localhost ([127.0.0.1]:43060 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h8QF6-0004eY-Lr for incoming@patchwork.ozlabs.org; Mon, 25 Mar 2019 10:06:24 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35128) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h8Q4B-0004Eg-V1 for qemu-devel@nongnu.org; Mon, 25 Mar 2019 09:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h8Q4A-0002cs-0o for qemu-devel@nongnu.org; Mon, 25 Mar 2019 09:55:07 -0400 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]:45909) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h8Q48-0002cS-1Z for qemu-devel@nongnu.org; Mon, 25 Mar 2019 09:55:05 -0400 Received: by mail-pf1-x42d.google.com with SMTP id e24so5625509pfi.12 for ; Mon, 25 Mar 2019 06:55:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GS/ATBmGIgxPYAiuJFaqFhojoguvyM891CV7uaCo/sw=; b=Fdw3obbcA1fmvu710uZoRoJC+OvivI7ML1qLfcrZmMf2kJ9wzX+5//sMRF/bEikfbY rJvOo8Jqb5ld30rbCiR9jQyyHJGKoRZQTkmXM0G2NepikCfCxN/tDvrlfN1jjZCKjo6d Vx59/ph0aiQzPIVoK/YtOQZ4sIkFo5AH8Yz/5u3woDz7dYwRlgGFYT+FTtJ+xQl1KL/J c9hhyi64EeoiJq3hkoX0iMUSzBM02g/MnbdRj91QV8WBmiT6NDDNudlUbUrWza8wHFCs BWR9XMNIVrJL7MWKkXjvazzcu8+m7A0i2e6rWWznCCP3MhSH2uVkNbMn9M6Bli6YjtIf 23Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GS/ATBmGIgxPYAiuJFaqFhojoguvyM891CV7uaCo/sw=; b=ioRBuB7Z6kQZ+f1EmnWy0iB3aKNJffwSi6SXGPd7MP5kF0wT/Khd9lB4xi9Dr9Q+Ok k2h5ZcuAjUR+0pI2+OFZsi7CkHqlbmfS4nVGJWzC5aZFOta87O9kbRZ8FMUPDN59dpUJ MvHsewhyCCRISDOsxcjnp9TFuBzGB0UtIZKfgCHgdhBvTHjXmHkFEBHrl80M8kNww2Gj QkbY2L2M39nJQ8ANsUT4+oeaxY1V7lICJ82ktpY2aWBvfxKzGjNolIOrqRv1BhPYC5MR kpXNsm6hAJ59hCqMWEyDbYN5as4CgvWCOR9wQo3afaORqEz5nDDgzi4UmIug4BR4KN3/ xZdQ== X-Gm-Message-State: APjAAAVB9DKN//Za8LBffbXVP+OyuCeG00uKvQsxqIYyFG8ClupqCkP7 VwgLjqiDmmKlhBWn4Hz254qVvozbvJY= X-Google-Smtp-Source: APXvYqwSBO5fkoIbCYdqhiZTePmc5Ir44L3DXrg94Qau16lf0z5QUdYEjY1u24mS0d5DN3VKJL9tDA== X-Received: by 2002:a63:e915:: with SMTP id i21mr23662418pgh.297.1553522102128; Mon, 25 Mar 2019 06:55:02 -0700 (PDT) Received: from bogon.bytedance.net ([61.120.150.76]) by smtp.gmail.com with ESMTPSA id j1sm18535207pgp.84.2019.03.25.06.54.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 25 Mar 2019 06:55:01 -0700 (PDT) From: Fei Li To: qemu-devel@nongnu.org Date: Mon, 25 Mar 2019 21:54:09 +0800 Message-Id: <20190325135411.26506-10-shirley17fei@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20190325135411.26506-1-shirley17fei@gmail.com> References: <20190325135411.26506-1-shirley17fei@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::42d Subject: [Qemu-devel] [PATCH v13 for-4.1 09/11] qemu_thread: supplement error handling for migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Juan Quintela , Markus Armbruster , Peter Xu , "Dr . David Alan Gilbert" , Fei Li , Gerd Hoffmann , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Fei Li Update qemu_thread_create()'s callers by - setting an error on qemu_thread_create() failure for callers that set an error on failure; - reporting the error and returning failure for callers that return an error code on failure; - reporting the error and setting some state for callers that just report errors and choose not to continue on. Besides, make compress_threads_save_cleanup() cope with partially initialized comp_param[i] to adapt to the new qemu_thread_create() failure case. Cc: Markus Armbruster Cc: Dr. David Alan Gilbert Cc: Juan Quintela Cc: "Peter Xu " Signed-off-by: Fei Li Reviewed-by: Dr. David Alan Gilbert --- migration/migration.c | 35 ++++++++++++++++-------- migration/postcopy-ram.c | 16 ++++++++--- migration/ram.c | 70 +++++++++++++++++++++++++++++++----------------- migration/savevm.c | 12 ++++++--- 4 files changed, 89 insertions(+), 44 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index e9e83ab564..05b20174c5 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -484,10 +484,13 @@ static void process_incoming_migration_co(void *opaque) goto fail; } - /* TODO: let the further caller handle the error instead of abort() */ - qemu_thread_create(&mis->colo_incoming_thread, "COLO incoming", - colo_process_incoming_thread, mis, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(&mis->colo_incoming_thread, "COLO incoming", + colo_process_incoming_thread, mis, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + error_reportf_err(local_err, "failed to create " + "colo_process_incoming_thread: "); + goto fail; + } mis->have_colo_incoming_thread = true; qemu_coroutine_yield(); @@ -2481,6 +2484,7 @@ out: static int open_return_path_on_source(MigrationState *ms, bool create_thread) { + Error *local_err = NULL; ms->rp_state.from_dst_file = qemu_file_get_return_path(ms->to_dst_file); if (!ms->rp_state.from_dst_file) { @@ -2494,10 +2498,15 @@ static int open_return_path_on_source(MigrationState *ms, return 0; } - /* TODO: let the further caller handle the error instead of abort() here */ - qemu_thread_create(&ms->rp_state.rp_thread, "return path", - source_return_path_thread, ms, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(&ms->rp_state.rp_thread, "return path", + source_return_path_thread, ms, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + error_reportf_err(local_err, + "failed to create source_return_path_thread: "); + qemu_fclose(ms->rp_state.from_dst_file); + ms->rp_state.from_dst_file = NULL; + return -1; + } trace_open_return_path_on_source_continue(); @@ -3342,9 +3351,13 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) migrate_fd_cleanup(s); return; } - /* TODO: let the further caller handle the error instead of abort() here */ - qemu_thread_create(&s->thread, "live_migration", migration_thread, s, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(&s->thread, "live_migration", migration_thread, s, + QEMU_THREAD_JOINABLE, &error_in) < 0) { + error_reportf_err(error_in, "failed to create migration_thread: "); + migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED); + migrate_fd_cleanup(s); + return; + } s->migration_thread_running = true; } diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index e9d69c8b1e..9df1995ed8 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -1089,6 +1089,8 @@ retry: int postcopy_ram_enable_notify(MigrationIncomingState *mis) { + Error *local_err = NULL; + /* Open the fd for the kernel to give us userfaults */ mis->userfault_fd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); if (mis->userfault_fd == -1) { @@ -1115,10 +1117,16 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis) } qemu_sem_init(&mis->fault_thread_sem, 0); - /* TODO: let the further caller handle the error instead of abort() here */ - qemu_thread_create(&mis->fault_thread, "postcopy/fault", - postcopy_ram_fault_thread, mis, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(&mis->fault_thread, "postcopy/fault", + postcopy_ram_fault_thread, mis, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + error_reportf_err(local_err, + "failed to create postcopy_ram_fault_thread: "); + close(mis->userfault_event_fd); + close(mis->userfault_fd); + qemu_sem_destroy(&mis->fault_thread_sem); + return -1; + } qemu_sem_wait(&mis->fault_thread_sem); qemu_sem_destroy(&mis->fault_thread_sem); mis->have_fault_thread = true; diff --git a/migration/ram.c b/migration/ram.c index 825d448b31..7007e4a5d7 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -504,6 +504,14 @@ static void compress_threads_save_cleanup(void) thread_count = migrate_compress_threads(); for (i = 0; i < thread_count; i++) { + qemu_mutex_lock(&comp_param[i].mutex); + comp_param[i].quit = true; + qemu_cond_signal(&comp_param[i].cond); + qemu_mutex_unlock(&comp_param[i].mutex); + + qemu_mutex_destroy(&comp_param[i].mutex); + qemu_cond_destroy(&comp_param[i].cond); + /* * we use it as a indicator which shows if the thread is * properly init'd or not @@ -511,15 +519,7 @@ static void compress_threads_save_cleanup(void) if (!comp_param[i].file) { break; } - - qemu_mutex_lock(&comp_param[i].mutex); - comp_param[i].quit = true; - qemu_cond_signal(&comp_param[i].cond); - qemu_mutex_unlock(&comp_param[i].mutex); - qemu_thread_join(compress_threads + i); - qemu_mutex_destroy(&comp_param[i].mutex); - qemu_cond_destroy(&comp_param[i].cond); deflateEnd(&comp_param[i].stream); g_free(comp_param[i].originbuf); qemu_fclose(comp_param[i].file); @@ -536,6 +536,7 @@ static void compress_threads_save_cleanup(void) static int compress_threads_save_setup(void) { int i, thread_count; + Error *local_err = NULL; if (!migrate_use_compression()) { return 0; @@ -546,6 +547,9 @@ static int compress_threads_save_setup(void) qemu_cond_init(&comp_done_cond); qemu_mutex_init(&comp_done_lock); for (i = 0; i < thread_count; i++) { + qemu_mutex_init(&comp_param[i].mutex); + qemu_cond_init(&comp_param[i].cond); + comp_param[i].quit = false; comp_param[i].originbuf = g_try_malloc(TARGET_PAGE_SIZE); if (!comp_param[i].originbuf) { goto exit; @@ -562,13 +566,16 @@ static int compress_threads_save_setup(void) */ comp_param[i].file = qemu_fopen_ops(NULL, &empty_ops); comp_param[i].done = true; - comp_param[i].quit = false; - qemu_mutex_init(&comp_param[i].mutex); - qemu_cond_init(&comp_param[i].cond); - /* TODO: let the further caller handle the error instead of abort() */ - qemu_thread_create(compress_threads + i, "compress", - do_data_compress, comp_param + i, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(compress_threads + i, "compress", + do_data_compress, comp_param + i, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + error_reportf_err(local_err, "failed to create do_data_compress: "); + deflateEnd(&comp_param[i].stream); + g_free(comp_param[i].originbuf); + qemu_fclose(comp_param[i].file); + comp_param[i].file = NULL; + goto exit; + } } return 0; @@ -1139,9 +1146,14 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque) p->c = QIO_CHANNEL(sioc); qio_channel_set_delay(p->c, false); p->running = true; - /* TODO: let the further caller handle the error instead of abort() */ - qemu_thread_create(&p->thread, p->name, multifd_send_thread, p, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(&p->thread, p->name, multifd_send_thread, p, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + migrate_set_error(migrate_get_current(), local_err); + error_reportf_err(local_err, + "failed to create multifd_send_thread: "); + multifd_save_cleanup(); + return; + } atomic_inc(&multifd_send_state->count); } @@ -1420,9 +1432,13 @@ bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp) p->num_packets = 1; p->running = true; - /* TODO: let the further caller handle the error instead of abort() here */ - qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + multifd_recv_terminate_threads(local_err); + error_propagate_prepend(errp, local_err, + "failed to create multifd_recv_thread: "); + return false; + } atomic_inc(&multifd_recv_state->count); return atomic_read(&multifd_recv_state->count) == migrate_multifd_channels(); @@ -3783,6 +3799,7 @@ static void compress_threads_load_cleanup(void) static int compress_threads_load_setup(QEMUFile *f) { int i, thread_count; + Error *local_err = NULL; if (!migrate_use_compression()) { return 0; @@ -3804,10 +3821,13 @@ static int compress_threads_load_setup(QEMUFile *f) qemu_cond_init(&decomp_param[i].cond); decomp_param[i].done = true; decomp_param[i].quit = false; - /* TODO: let the further caller handle the error instead of abort() */ - qemu_thread_create(decompress_threads + i, "decompress", - do_data_decompress, decomp_param + i, - QEMU_THREAD_JOINABLE, &error_abort); + if (qemu_thread_create(decompress_threads + i, "decompress", + do_data_decompress, decomp_param + i, + QEMU_THREAD_JOINABLE, &local_err) < 0) { + error_reportf_err(local_err, + "failed to create do_data_decompress: "); + goto exit; + } } return 0; exit: diff --git a/migration/savevm.c b/migration/savevm.c index 8cd558be7e..67d6192317 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1832,10 +1832,14 @@ static int loadvm_postcopy_handle_listen(MigrationIncomingState *mis) mis->have_listen_thread = true; /* Start up the listening thread and wait for it to signal ready */ qemu_sem_init(&mis->listen_thread_sem, 0); - /* TODO: let the further caller handle the error instead of abort() here */ - qemu_thread_create(&mis->listen_thread, "postcopy/listen", - postcopy_ram_listen_thread, NULL, - QEMU_THREAD_DETACHED, &error_abort); + if (qemu_thread_create(&mis->listen_thread, "postcopy/listen", + postcopy_ram_listen_thread, NULL, + QEMU_THREAD_DETACHED, &local_err) < 0) { + error_reportf_err(local_err, + "failed to create postcopy_ram_listen_thread: "); + qemu_sem_destroy(&mis->listen_thread_sem); + return -1; + } qemu_sem_wait(&mis->listen_thread_sem); qemu_sem_destroy(&mis->listen_thread_sem);