From nobody Wed Nov 5 07:32:47 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1533616818224911.5690506345269; Mon, 6 Aug 2018 21:40:18 -0700 (PDT) Received: from localhost ([::1]:37287 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fmtn1-0001W0-WB for importer@patchew.org; Tue, 07 Aug 2018 00:40:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53953) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fmth4-0004gk-0E for qemu-devel@nongnu.org; Tue, 07 Aug 2018 00:34:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fmth1-0001HW-Jb for qemu-devel@nongnu.org; Tue, 07 Aug 2018 00:34:01 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:45956 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fmtgv-0001Bm-OU; Tue, 07 Aug 2018 00:33:54 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 56B7F81663C7; Tue, 7 Aug 2018 04:33:51 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-197.bos.redhat.com [10.18.17.197]) by smtp.corp.redhat.com (Postfix) with ESMTP id 08AD1202706B; Tue, 7 Aug 2018 04:33:51 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 7 Aug 2018 00:33:30 -0400 Message-Id: <20180807043349.27196-3-jsnow@redhat.com> In-Reply-To: <20180807043349.27196-1-jsnow@redhat.com> References: <20180807043349.27196-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 07 Aug 2018 04:33:51 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 07 Aug 2018 04:33:51 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 02/21] jobs: add exit shim 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: kwolf@redhat.com, John Snow , Jeff Cody , Markus Armbruster , "Dr. David Alan Gilbert" , jtc@redhat.com, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Most jobs do the same thing when they leave their running loop: - Store the return code in a structure - wait to receive this structure in the main thread - signal job completion via job_completed More seriously, when we utilize job_defer_to_main_loop_bh to call a function that calls job_completed, job_finalize_single will run in a context where it has recursively taken the aio_context lock, which can cause hangs if it puts down a reference that causes a flush. The job infrastructure is perfectly capable of registering job completion itself when we leave the job's entry point. In this context, we can signal job completion from outside of the aio_context, which should allow for job cleanup code to run with only one lock. Signed-off-by: John Snow Reviewed-by: Jeff Cody --- include/qemu/job.h | 7 +++++++ job.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/qemu/job.h b/include/qemu/job.h index 845ad00c03..0c24e8704f 100644 --- a/include/qemu/job.h +++ b/include/qemu/job.h @@ -204,6 +204,13 @@ struct JobDriver { */ void (*drain)(Job *job); =20 + /** + * If the callback is not NULL, exit will be invoked from the main thr= ead + * when the job's coroutine has finished, but before transactional + * convergence; before @prepare or @abort. + */ + void (*exit)(Job *job); + /** * If the callback is not NULL, prepare will be invoked when all the j= obs * belonging to the same transaction complete; or upon this job's comp= letion diff --git a/job.c b/job.c index b281f30375..cc5ac9ac30 100644 --- a/job.c +++ b/job.c @@ -535,6 +535,19 @@ void job_drain(Job *job) } } =20 +static void job_exit(void *opaque) +{ + Job *job =3D (Job *)opaque; + AioContext *aio_context =3D job->aio_context; + + if (job->driver->exit) { + aio_context_acquire(aio_context); + job->driver->exit(job); + aio_context_release(aio_context); + } + job_completed(job, job->ret); +} + /** * All jobs must allow a pause point before entering their job proper. This * ensures that jobs can be paused prior to being started, then resumed la= ter. @@ -546,6 +559,12 @@ static void coroutine_fn job_co_entry(void *opaque) assert(job && job->driver && job->driver->start); job_pause_point(job); job->driver->start(job); + if (!job->deferred_to_main_loop) { + job->deferred_to_main_loop =3D true; + aio_bh_schedule_oneshot(qemu_get_aio_context(), + job_exit, + job); + } } =20 =20 --=20 2.14.4