From patchwork Mon Nov 20 02:46:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 10065875 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 31CBE60597 for ; Mon, 20 Nov 2017 02:48:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A6C828C2C for ; Mon, 20 Nov 2017 02:48:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2EA7B28C71; Mon, 20 Nov 2017 02:48:49 +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 D229628C2C for ; Mon, 20 Nov 2017 02:48:48 +0000 (UTC) Received: from localhost ([::1]:55098 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eGc8d-00010X-Qp for patchwork-qemu-devel@patchwork.kernel.org; Sun, 19 Nov 2017 21:48:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56950) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eGc74-0000bl-FD for qemu-devel@nongnu.org; Sun, 19 Nov 2017 21:47:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eGc71-0008Ob-CO for qemu-devel@nongnu.org; Sun, 19 Nov 2017 21:47:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36502) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eGc6z-0008M8-4d; Sun, 19 Nov 2017 21:47:05 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 409A8FC7AA; Mon, 20 Nov 2017 02:47:04 +0000 (UTC) Received: from localhost (ovpn-124-90.rdu2.redhat.com [10.10.124.90]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CEFD664444; Mon, 20 Nov 2017 02:47:03 +0000 (UTC) From: Jeff Cody To: qemu-devel@nongnu.org Date: Sun, 19 Nov 2017 21:46:44 -0500 Message-Id: <0c039d00e03331d863ee249810d9778313670803.1511145863.git.jcody@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 20 Nov 2017 02:47:04 +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 3/5] coroutines: abort if we try to enter a still-sleeping coroutine 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 Once a coroutine is "sleeping", the timer callback will either enter the coroutine, or schedule it for the next AioContext if using iothreads. It is illegal to enter that coroutine while waiting for this timer event and subsequent callback. This patch will catch such an attempt, and abort QEMU with an error. Like with the previous patch, we cannot rely solely on the co->caller check for recursive entry. The prematurely entered coroutine may exit with COROUTINE_TERMINATE before the timer expires, making co->caller no longer valid. We can clear co->sleeping in in co_sleep_cb(), because any doubly entry attempt after point should be caught by either the co->scheduled or co->caller checks. Signed-off-by: Jeff Cody --- include/qemu/coroutine_int.h | 2 ++ util/qemu-coroutine-sleep.c | 3 +++ util/qemu-coroutine.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h index 931cdc9..b071217 100644 --- a/include/qemu/coroutine_int.h +++ b/include/qemu/coroutine_int.h @@ -56,6 +56,8 @@ struct Coroutine { int scheduled; + int sleeping; + QSIMPLEQ_ENTRY(Coroutine) co_queue_next; QSLIST_ENTRY(Coroutine) co_scheduled_next; }; diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c index 9c56550..11ae95a 100644 --- a/util/qemu-coroutine-sleep.c +++ b/util/qemu-coroutine-sleep.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "qemu/coroutine.h" +#include "qemu/coroutine_int.h" #include "qemu/timer.h" #include "block/aio.h" @@ -25,6 +26,7 @@ static void co_sleep_cb(void *opaque) { CoSleepCB *sleep_cb = opaque; + sleep_cb->co->sleeping = 0; aio_co_wake(sleep_cb->co); } @@ -34,6 +36,7 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type, CoSleepCB sleep_cb = { .co = qemu_coroutine_self(), }; + sleep_cb.co->sleeping = 1; sleep_cb.ts = aio_timer_new(ctx, type, SCALE_NS, co_sleep_cb, &sleep_cb); timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns); qemu_coroutine_yield(); diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c index 2edab63..1d9f93d 100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@ -118,6 +118,11 @@ void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co) abort(); } + if (co->sleeping == 1) { + fprintf(stderr, "Cannot enter a co-routine that is still sleeping\n"); + abort(); + } + if (co->caller) { fprintf(stderr, "Co-routine re-entered recursively\n"); abort();