From patchwork Thu Jan 28 07:02:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fam Zheng X-Patchwork-Id: 8146841 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 66C639F818 for ; Thu, 28 Jan 2016 07:04:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C63BD20320 for ; Thu, 28 Jan 2016 07:04:25 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1AF3E20303 for ; Thu, 28 Jan 2016 07:04:25 +0000 (UTC) Received: from localhost ([::1]:54301 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aOgcy-00011r-HJ for patchwork-qemu-devel@patchwork.kernel.org; Thu, 28 Jan 2016 02:04:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37526) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aOgbz-0007p7-En for qemu-devel@nongnu.org; Thu, 28 Jan 2016 02:03:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aOgby-0007ct-IY for qemu-devel@nongnu.org; Thu, 28 Jan 2016 02:03:23 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43950) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aOgbt-0007bm-KD; Thu, 28 Jan 2016 02:03:17 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 18A7C8F2E4; Thu, 28 Jan 2016 07:03:17 +0000 (UTC) Received: from fam-t430.redhat.com (vpn1-5-202.pek2.redhat.com [10.72.5.202]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u0S72qKC030641; Thu, 28 Jan 2016 02:03:11 -0500 From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 28 Jan 2016 15:02:51 +0800 Message-Id: <1453964571-23016-3-git-send-email-famz@redhat.com> In-Reply-To: <1453964571-23016-1-git-send-email-famz@redhat.com> References: <1453964571-23016-1-git-send-email-famz@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , qemu-block@nongnu.org, Jeff Cody , mreitz@redhat.com, stefanha@redhat.com, jsnow@redhat.com Subject: [Qemu-devel] [PATCH 2/2] blockjob: Fix hang in block_job_finish_sync X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP With a mirror job running on a virtio-blk dataplane disk, sending "q" to HMP will cause a dead loop in block_job_finish_sync. This is because the aio_poll() only processes the AIO context of bs which has no more work to do, while the main loop BH that is scheduled for setting the job->completed flag is never processed. Fix this by adding a "ctx" pointer in BlockJob structure, to track which context to poll for the block job to make progress. Its value is set to the BDS context at block job creation, until block_job_coroutine_complete() is called by the block job coroutine. After that point, the block job's work is deferred to main loop BH. Signed-off-by: Fam Zheng --- blockjob.c | 4 +++- include/block/blockjob.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/blockjob.c b/blockjob.c index 4b16720..4ea1ce0 100644 --- a/blockjob.c +++ b/blockjob.c @@ -74,6 +74,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs, job->opaque = opaque; job->busy = true; job->refcnt = 1; + job->ctx = bdrv_get_aio_context(bs); bs->job = job; /* Only set speed when necessary to avoid NotSupported error */ @@ -304,7 +305,7 @@ static int block_job_finish_sync(BlockJob *job, return -EBUSY; } while (!job->completed) { - aio_poll(bdrv_get_aio_context(bs), true); + aio_poll(job->ctx, true); } ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret; block_job_unref(job); @@ -497,6 +498,7 @@ void block_job_coroutine_complete(BlockJob *job, data->aio_context = bdrv_get_aio_context(job->bs); data->fn = fn; data->opaque = opaque; + job->ctx = qemu_get_aio_context(); qemu_bh_schedule(data->bh); } diff --git a/include/block/blockjob.h b/include/block/blockjob.h index de59fc2..5c6a884 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -92,6 +92,8 @@ struct BlockJob { */ char *id; + AioContext *ctx; + /** * The coroutine that executes the job. If not NULL, it is * reentered when busy is false and the job is cancelled.