From patchwork Mon Nov 20 02:46:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 10065881 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 014BF60597 for ; Mon, 20 Nov 2017 02:51:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A1AB28DB2 for ; Mon, 20 Nov 2017 02:51:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F141E28DEF; Mon, 20 Nov 2017 02:51:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 8D0A028DB2 for ; Mon, 20 Nov 2017 02:51:03 +0000 (UTC) Received: from localhost ([::1]:55110 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eGcAo-000343-NH for patchwork-qemu-devel@patchwork.kernel.org; Sun, 19 Nov 2017 21:51:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56928) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eGc71-0000ax-9j for qemu-devel@nongnu.org; Sun, 19 Nov 2017 21:47:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eGc70-0008ON-Dd for qemu-devel@nongnu.org; Sun, 19 Nov 2017 21:47:07 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51574) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eGc6x-0008K4-TX; Sun, 19 Nov 2017 21:47:04 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F31FE7E390; Mon, 20 Nov 2017 02:47:02 +0000 (UTC) Received: from localhost (ovpn-124-90.rdu2.redhat.com [10.10.124.90]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9D7A660BE5; Mon, 20 Nov 2017 02:47:01 +0000 (UTC) From: Jeff Cody To: qemu-devel@nongnu.org Date: Sun, 19 Nov 2017 21:46:43 -0500 Message-Id: <5bec37564f83e39e216d2ebcf7a380b0c7704e0e.1511145863.git.jcody@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 20 Nov 2017 02:47:03 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/5] coroutine: abort if we try to enter coroutine scheduled for another ctx 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, famz@redhat.com, qemu-block@nongnu.org, mreitz@redhat.com, stefanha@redhat.com, pbonzini@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The previous patch fixed a race condition, in which there were coroutines being executing doubly, or after coroutine deletion. We can detect common scenarios when this happens, and print an error and abort before we corrupt memory / data, or segfault. This patch will abort if an attempt to enter a coroutine is made while it is currently pending execution in a different AioContext. We cannot rely on the existing co->caller check for recursive re-entry to catch this, as the coroutine may run and exit with COROUTINE_TERMINATE before the AioContext scheduled event happens. (This is the scenario that was occuring and fixed in the previous patch). Signed-off-by: Jeff Cody --- include/qemu/coroutine_int.h | 3 +++ util/async.c | 7 +++++++ util/qemu-coroutine.c | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h index cb98892..931cdc9 100644 --- a/include/qemu/coroutine_int.h +++ b/include/qemu/coroutine_int.h @@ -53,6 +53,9 @@ struct Coroutine { /* Only used when the coroutine has yielded. */ AioContext *ctx; + + int scheduled; + QSIMPLEQ_ENTRY(Coroutine) co_queue_next; QSLIST_ENTRY(Coroutine) co_scheduled_next; }; diff --git a/util/async.c b/util/async.c index 0e1bd87..d459684 100644 --- a/util/async.c +++ b/util/async.c @@ -388,6 +388,7 @@ static void co_schedule_bh_cb(void *opaque) QSLIST_REMOVE_HEAD(&straight, co_scheduled_next); trace_aio_co_schedule_bh_cb(ctx, co); aio_context_acquire(ctx); + co->scheduled = 0; qemu_coroutine_enter(co); aio_context_release(ctx); } @@ -438,6 +439,12 @@ fail: void aio_co_schedule(AioContext *ctx, Coroutine *co) { trace_aio_co_schedule(ctx, co); + if (co->scheduled == 1) { + fprintf(stderr, + "Cannot schedule a co-routine that is already scheduled\n"); + abort(); + } + co->scheduled = 1; QSLIST_INSERT_HEAD_ATOMIC(&ctx->scheduled_coroutines, co, co_scheduled_next); qemu_bh_schedule(ctx->co_schedule_bh); diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c index d6095c1..2edab63 100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@ -109,6 +109,15 @@ void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co) trace_qemu_aio_coroutine_enter(ctx, self, co, co->entry_arg); + /* if the Coroutine has already been scheduled, entering it again will + * cause us to enter it twice, potentially even after the coroutine has + * been deleted */ + if (co->scheduled == 1) { + fprintf(stderr, "Cannot enter a co-routine that has already " + "been scheduled to run in a different AioContext\n"); + abort(); + } + if (co->caller) { fprintf(stderr, "Co-routine re-entered recursively\n"); abort();