From nobody Sat May 4 22:30:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass header.i=@amazon.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=amazon.com ARC-Seal: i=1; a=rsa-sha256; t=1576506985; cv=none; d=zohomail.com; s=zohoarc; b=RGCA44JbVUyKsodoAXzDIwK7p0xifrD5yjWaW2g7exos5tZ2n4a8ZsJLATt7UQknzw0w6+k9NyzisQu4VfPddKwK3DjmI9/M7DYdDWp5fPhv9UdjWhPalWXoieroLjUZgMMHfPNfMjyNOKlQCUy2iscp56iPuNhYjN7JZpqWV48= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1576506985; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=mo5tkH2WlUm0uRAeRwD/f8E6x/WRLfP+Q3QUirldoBo=; b=IrXR20tdw/VLdy1IPBcf82XoOIXdUTdoOEq2Oecw3A2XyIBNDs2dvNxWh4KmP4+04WSh7N2uQZsToEzKTmH1lMBQUlP4GI80GfAJOeMqYY4ALwjhq0IKxzkP91Vs8bsii6Yi65yG1UUMpFJs2CgpnJBI2xyt4ZJiNMyCyuzx/JE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@amazon.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1576506985911345.80414303766236; Mon, 16 Dec 2019 06:36:25 -0800 (PST) Received: from localhost ([::1]:54814 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1igrTz-00038O-Su for importer@patchew.org; Mon, 16 Dec 2019 09:36:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41022) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1igrT1-0002Z3-SM for qemu-devel@nongnu.org; Mon, 16 Dec 2019 09:35:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1igrT0-0002p3-Ea for qemu-devel@nongnu.org; Mon, 16 Dec 2019 09:35:23 -0500 Received: from smtp-fw-9101.amazon.com ([207.171.184.25]:31416) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1igrSv-0002nZ-Bo; Mon, 16 Dec 2019 09:35:17 -0500 Received: from sea32-co-svc-lb4-vlan3.sea.corp.amazon.com (HELO email-inbound-relay-1d-38ae4ad2.us-east-1.amazon.com) ([10.47.23.38]) by smtp-border-fw-out-9101.sea19.amazon.com with ESMTP; 16 Dec 2019 14:35:05 +0000 Received: from EX13MTAUEA001.ant.amazon.com (iad55-ws-svc-p15-lb9-vlan3.iad.amazon.com [10.40.159.166]) by email-inbound-relay-1d-38ae4ad2.us-east-1.amazon.com (Postfix) with ESMTPS id 16CDAA27C5; Mon, 16 Dec 2019 14:35:02 +0000 (UTC) Received: from EX13D32EUB001.ant.amazon.com (10.43.166.125) by EX13MTAUEA001.ant.amazon.com (10.43.61.243) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Mon, 16 Dec 2019 14:35:01 +0000 Received: from EX13MTAUWA001.ant.amazon.com (10.43.160.58) by EX13D32EUB001.ant.amazon.com (10.43.166.125) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Mon, 16 Dec 2019 14:35:00 +0000 Received: from u2f063a87eabd5f.cbg10.amazon.com (10.125.106.135) by mail-relay.amazon.com (10.43.160.118) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Mon, 16 Dec 2019 14:34:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1576506918; x=1608042918; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=mo5tkH2WlUm0uRAeRwD/f8E6x/WRLfP+Q3QUirldoBo=; b=I4ZfteFXWS7YhFRafp+xo4VqYowJwG0aJbcNTkWXqSUu1y+egSsBtNz8 83+NhQ246oMdtiu2xSt/t2qEnr0IBHUnYUti0l2MGjatRCIHYKKWnqRA8 vonariUkh730NqGw5NCeSa14GIDCWuQzq6s2foJHx2i8O3uj0Dsn6k/WB A=; IronPort-SDR: HvceauYoX5O6jdFTstyRE1PiDVuS1O9t0RZUEsmrZNMeHtOkokM5ubMiT+imvBBTZd44HJOFlB 7Qd0Fug4EkVw== X-IronPort-AV: E=Sophos;i="5.69,321,1571702400"; d="scan'208";a="5372634" From: Paul Durrant To: , , CC: Paul Durrant , Julien Grall , Stefano Stabellini , Anthony Perard , Stefan Hajnoczi , "Kevin Wolf" , Max Reitz Subject: [PATCH] xen-bus/block: explicitly assign event channels to an AioContext Date: Mon, 16 Dec 2019 14:34:51 +0000 Message-ID: <20191216143451.19024-1-pdurrant@amazon.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: Bulk X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x [fuzzy] X-Received-From: 207.171.184.25 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @amazon.com) Content-Type: text/plain; charset="utf-8" It is not safe to close an event channel from the QEMU main thread when that channel's poller is running in IOThread context. This patch adds a new xen_device_set_event_channel_context() function to explicitly assign the channel AioContext, and modifies xen_device_bind_event_channel() to initially assign the channel's poller to the QEMU main thread context. The code in xen-block's dataplane is then modified to assign the channel to IOThread context during xen_block_dataplane_start() and de-assign it during in xen_block_dataplane_stop(), such that the channel is always assigned back to main thread context before it is closed. aio_set_fd_handler() already deals with all the necessary synchronization when moving an fd between AioContext-s so no extra code is needed to manage this. Reported-by: Julien Grall Signed-off-by: Paul Durrant Reviewed-by: Anthony PERARD --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Stefan Hajnoczi Cc: Kevin Wolf Cc: Max Reitz Tested against an HVM debian guest with a QCOW2 image as system disk, and as a hot-plugged/unplgged secondary disk. --- hw/block/dataplane/xen-block.c | 20 ++++++++++++++++++-- hw/xen/xen-bus.c | 27 +++++++++++++++++++++++---- include/hw/xen/xen-bus.h | 5 ++++- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 3b9caeb2fa..288a87a814 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -685,12 +685,24 @@ void xen_block_dataplane_stop(XenBlockDataPlane *data= plane) return; } =20 + xendev =3D dataplane->xendev; + aio_context_acquire(dataplane->ctx); + if (dataplane->event_channel) { + /* Only reason for failure is a NULL channel */ + xen_device_set_event_channel_context(xendev, dataplane->event_chan= nel, + qemu_get_aio_context(), + &error_abort); + } /* Xen doesn't have multiple users for nodes, so this can't fail */ blk_set_aio_context(dataplane->blk, qemu_get_aio_context(), &error_abo= rt); aio_context_release(dataplane->ctx); =20 - xendev =3D dataplane->xendev; + /* + * Now that the context has been moved onto the main thread, cancel + * further processing. + */ + qemu_bh_cancel(dataplane->bh); =20 if (dataplane->event_channel) { Error *local_err =3D NULL; @@ -807,7 +819,7 @@ void xen_block_dataplane_start(XenBlockDataPlane *datap= lane, } =20 dataplane->event_channel =3D - xen_device_bind_event_channel(xendev, dataplane->ctx, event_channe= l, + xen_device_bind_event_channel(xendev, event_channel, xen_block_dataplane_event, dataplane, &local_err); if (local_err) { @@ -818,7 +830,11 @@ void xen_block_dataplane_start(XenBlockDataPlane *data= plane, aio_context_acquire(dataplane->ctx); /* If other users keep the BlockBackend in the iothread, that's ok */ blk_set_aio_context(dataplane->blk, dataplane->ctx, NULL); + /* Only reason for failure is a NULL channel */ + xen_device_set_event_channel_context(xendev, dataplane->event_channel, + dataplane->ctx, &error_abort); aio_context_release(dataplane->ctx); + return; =20 stop: diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index c2ad22a42d..349856b32b 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -1089,8 +1089,26 @@ static void xen_device_event(void *opaque) } } =20 +void xen_device_set_event_channel_context(XenDevice *xendev, + XenEventChannel *channel, + AioContext *ctx, + Error **errp) +{ + if (!channel) { + error_setg(errp, "bad channel"); + return; + } + + if (channel->ctx) + aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + NULL, NULL, NULL, NULL); + + channel->ctx =3D ctx; + aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + xen_device_event, NULL, xen_device_poll, channel); +} + XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, - AioContext *ctx, unsigned int port, XenEventHandler handler, void *opaque, Error **errp) @@ -1116,9 +1134,10 @@ XenEventChannel *xen_device_bind_event_channel(XenDe= vice *xendev, channel->handler =3D handler; channel->opaque =3D opaque; =20 - channel->ctx =3D ctx; - aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, - xen_device_event, NULL, xen_device_poll, channel); + /* Only reason for failure is a NULL channel */ + xen_device_set_event_channel_context(xendev, channel, + qemu_get_aio_context(), + &error_abort); =20 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list); =20 diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 3d5532258d..c18c1372af 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -128,10 +128,13 @@ void xen_device_copy_grant_refs(XenDevice *xendev, bo= ol to_domain, typedef bool (*XenEventHandler)(void *opaque); =20 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, - AioContext *ctx, unsigned int port, XenEventHandler handler, void *opaque, Error **errp); +void xen_device_set_event_channel_context(XenDevice *xendev, + XenEventChannel *channel, + AioContext *ctx, + Error **errp); void xen_device_notify_event_channel(XenDevice *xendev, XenEventChannel *channel, Error **errp); --=20 2.20.1