From nobody Sat May 18 23:44:17 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=fail; 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=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1586454208; cv=none; d=zohomail.com; s=zohoarc; b=ACl97AWvjDH43lHkVJPrtX/vz1ujpXYdybHWWzhkJzJfv3c7XGllibD9Qaspnfqkj8PXe/7xmL9Y7JAcEWCkv54SGaBgUhrvZPreInUxGEmpWBdXJCavfmxm3xbAB4L5cO+R6CrxyL4MnHTC9eeQGx7KHlsiiXqW2gl2lnUoFEk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1586454208; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=wVF2oPLokgrMjXng0KIWWIEZOasxYMIOjCTJUOruRE0=; b=Nf1cP1aMw2MWSguEEc2bXuNDscGzqNaz1e1+xYVtrxjvfUjODNZprXnNvu9a0RmsvC5rkI2XgXnJx/m3zBWS1k7cKsdNphSbh6mBFr6NtgCM8lyiS3GDI/GVE8gzD4zOiyPuxqTI5gVQr2j3rYjaX+qxlXNkZwA2i3fmztC+BOA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; 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=fail header.from= (p=none 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 1586454208719657.4586005099682; Thu, 9 Apr 2020 10:43:28 -0700 (PDT) Received: from localhost ([::1]:53400 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMbD5-00076d-Gj for importer@patchew.org; Thu, 09 Apr 2020 13:43:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39463) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMbC6-0005Oj-C1 for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jMbC5-0006oP-EP for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:26 -0400 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:38455 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jMbC5-0006o6-AP for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:25 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-446-VquynQwiM96o-gkPNuv33Q-1; Thu, 09 Apr 2020 13:42:23 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C81851084457; Thu, 9 Apr 2020 17:42:21 +0000 (UTC) Received: from localhost (ovpn-114-141.ams2.redhat.com [10.36.114.141]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8F4FD391; Thu, 9 Apr 2020 17:42:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1586454145; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wVF2oPLokgrMjXng0KIWWIEZOasxYMIOjCTJUOruRE0=; b=dG9dufzn2/HTNSXaVViBDH3MH7vxS6FDHI1UqxdJzEHb8VgniTpoWvLld4aPi6UXhnqnKK 6DSfoGvU8Rvej9cort3ri805/1XnNOVwTlmG5jPwtCwDgevCmv3nfCYfIe2jy4hQ07laI5 RIHmQJZJQ/SR34aT/UV62GD5ty4uW2c= X-MC-Unique: VquynQwiM96o-gkPNuv33Q-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [PULL for-5.0 1/3] aio-posix: signal-proof fdmon-io_uring Date: Thu, 9 Apr 2020 18:42:07 +0100 Message-Id: <20200409174209.321725-2-stefanha@redhat.com> In-Reply-To: <20200409174209.321725-1-stefanha@redhat.com> References: <20200409174209.321725-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Maydell , qemu-block@nongnu.org, Stefan Weil , Max Reitz , Stefan Hajnoczi , Paolo Bonzini , Fam Zheng , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Stefano Garzarella Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" The io_uring_enter(2) syscall returns with errno=3DEINTR when interrupted by a signal. Retry the syscall in this case. It's essential to do this in the io_uring_submit_and_wait() case. My interpretation of the Linux v5.5 io_uring_enter(2) code is that it shouldn't affect the io_uring_submit() case, but there is no guarantee this will always be the case. Let's check for -EINTR around both APIs. Note that the liburing APIs have -errno return values. Signed-off-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Reviewed-by: Philippe Mathieu-Daud=C3=A9 Message-id: 20200408091139.273851-1-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- util/fdmon-io_uring.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c index b4d6109f20..d5a80ed6fb 100644 --- a/util/fdmon-io_uring.c +++ b/util/fdmon-io_uring.c @@ -88,7 +88,10 @@ static struct io_uring_sqe *get_sqe(AioContext *ctx) } =20 /* No free sqes left, submit pending sqes first */ - ret =3D io_uring_submit(ring); + do { + ret =3D io_uring_submit(ring); + } while (ret =3D=3D -EINTR); + assert(ret > 1); sqe =3D io_uring_get_sqe(ring); assert(sqe); @@ -282,7 +285,10 @@ static int fdmon_io_uring_wait(AioContext *ctx, AioHan= dlerList *ready_list, =20 fill_sq_ring(ctx); =20 - ret =3D io_uring_submit_and_wait(&ctx->fdmon_io_uring, wait_nr); + do { + ret =3D io_uring_submit_and_wait(&ctx->fdmon_io_uring, wait_nr); + } while (ret =3D=3D -EINTR); + assert(ret >=3D 0); =20 return process_cq_ring(ctx, ready_list); --=20 2.25.1 From nobody Sat May 18 23:44:17 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=fail; 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=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1586454208; cv=none; d=zohomail.com; s=zohoarc; b=PXo3LgYx084Hut0fh/3JntrIxnh8dwqmrPebBdgLDtMGtq9MG/VLvwUddMQeeyYuwNG+XpQ0llZaZee09sl6Ee2u2RNfFK8VanLHkDmJp5Dg+bFBhIN5zOPAAZrFlhpSZmEdV812KsS/cnmBtCEiDEOOHXAEGSHrMshNQj1Kxlo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1586454208; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0zq38BUlrj/isy7pME+Q9jm+00Jwv5PAkZjHQUQ5kxo=; b=SSSIA5AVurwJ3DPySOdsn1Y+8Y+hzwYb6aD8ACKckCltDUK/z1fZoZkfp+g1eR8RzKw2h2uAZ7lSh92KxO2iIbABQJgRya0MMvVvwUwvuvKKxFkYOLgHCGW3Sz1xuEDyEY8CA7ufS39pQefRtW8fF4xKvUw5uixjHOYrpp18CA0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; 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=fail header.from= (p=none 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 1586454208683200.25243036725885; Thu, 9 Apr 2020 10:43:28 -0700 (PDT) Received: from localhost ([::1]:53398 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMbD5-000745-Bv for importer@patchew.org; Thu, 09 Apr 2020 13:43:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39483) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMbC9-0005TD-JI for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jMbC7-0006pm-8W for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:29 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:51682 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jMbC7-0006pU-4t for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:27 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-197-NgQl9B4HPLSsDAxMoL9b9g-1; Thu, 09 Apr 2020 13:42:24 -0400 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6EEEA1922963; Thu, 9 Apr 2020 17:42:23 +0000 (UTC) Received: from localhost (ovpn-114-141.ams2.redhat.com [10.36.114.141]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0819C1195A6; Thu, 9 Apr 2020 17:42:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1586454146; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0zq38BUlrj/isy7pME+Q9jm+00Jwv5PAkZjHQUQ5kxo=; b=Wv7xAHPjNkDHAUEll4tqvlPFYtZEqIq+JvwhWmhHcbF/a3meLT0Mt/yeFoIKsUIPHZlHzy n2JO3HO0RWm5CULC0v6SGjUusvmQQE7ena2EecYpSxBTtj3oIYGxctZTnCG53zs00kea6L LP4pECKbaFnDjiEtNNeKIZPyAa9qJVM= X-MC-Unique: NgQl9B4HPLSsDAxMoL9b9g-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [PULL for-5.0 2/3] aio-wait: delegate polling of main AioContext if BQL not held Date: Thu, 9 Apr 2020 18:42:08 +0100 Message-Id: <20200409174209.321725-3-stefanha@redhat.com> In-Reply-To: <20200409174209.321725-1-stefanha@redhat.com> References: <20200409174209.321725-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Maydell , qemu-block@nongnu.org, Stefan Weil , Max Reitz , Stefan Hajnoczi , Paolo Bonzini , Fam Zheng Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Paolo Bonzini Any thread that is not a iothread returns NULL for qemu_get_current_aio_con= text(). As a result, it would also return true for in_aio_context_home_thread(qemu_get_aio_context()), causing AIO_WAIT_WHILE to invoke aio_poll() directly. This is incorrect if the BQL is not held, because aio_poll() does not expect to run concurrently from multiple threads, and it can actually happen when savevm writes to the vmstate file from the migration thread. Therefore, restrict in_aio_context_home_thread to return true for the main AioContext only if the BQL is held. The function is moved to aio-wait.h because it is mostly used there and to avoid a circular reference between main-loop.h and block/aio.h. Signed-off-by: Paolo Bonzini Message-Id: <20200407140746.8041-5-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- include/block/aio-wait.h | 22 ++++++++++++++++++++++ include/block/aio.h | 29 ++++++++++------------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h index afeeb18f95..716d2639df 100644 --- a/include/block/aio-wait.h +++ b/include/block/aio-wait.h @@ -26,6 +26,7 @@ #define QEMU_AIO_WAIT_H =20 #include "block/aio.h" +#include "qemu/main-loop.h" =20 /** * AioWait: @@ -124,4 +125,25 @@ void aio_wait_kick(void); */ void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque); =20 +/** + * in_aio_context_home_thread: + * @ctx: the aio context + * + * Return whether we are running in the thread that normally runs @ctx. N= ote + * that acquiring/releasing ctx does not affect the outcome, each AioConte= xt + * still only has one home thread that is responsible for running it. + */ +static inline bool in_aio_context_home_thread(AioContext *ctx) +{ + if (ctx =3D=3D qemu_get_current_aio_context()) { + return true; + } + + if (ctx =3D=3D qemu_get_aio_context()) { + return qemu_mutex_iothread_locked(); + } else { + return false; + } +} + #endif /* QEMU_AIO_WAIT_H */ diff --git a/include/block/aio.h b/include/block/aio.h index cb1989105a..62ed954344 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -133,12 +133,16 @@ struct AioContext { AioHandlerList deleted_aio_handlers; =20 /* Used to avoid unnecessary event_notifier_set calls in aio_notify; - * accessed with atomic primitives. If this field is 0, everything - * (file descriptors, bottom halves, timers) will be re-evaluated - * before the next blocking poll(), thus the event_notifier_set call - * can be skipped. If it is non-zero, you may need to wake up a - * concurrent aio_poll or the glib main event loop, making - * event_notifier_set necessary. + * only written from the AioContext home thread, or under the BQL in + * the case of the main AioContext. However, it is read from any + * thread so it is still accessed with atomic primitives. + * + * If this field is 0, everything (file descriptors, bottom halves, + * timers) will be re-evaluated before the next blocking poll() or + * io_uring wait; therefore, the event_notifier_set call can be + * skipped. If it is non-zero, you may need to wake up a concurrent + * aio_poll or the glib main event loop, making event_notifier_set + * necessary. * * Bit 0 is reserved for GSource usage of the AioContext, and is 1 * between a call to aio_ctx_prepare and the next call to aio_ctx_chec= k. @@ -681,19 +685,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *c= o); */ AioContext *qemu_get_current_aio_context(void); =20 -/** - * in_aio_context_home_thread: - * @ctx: the aio context - * - * Return whether we are running in the thread that normally runs @ctx. N= ote - * that acquiring/releasing ctx does not affect the outcome, each AioConte= xt - * still only has one home thread that is responsible for running it. - */ -static inline bool in_aio_context_home_thread(AioContext *ctx) -{ - return ctx =3D=3D qemu_get_current_aio_context(); -} - /** * aio_context_setup: * @ctx: the aio context --=20 2.25.1 From nobody Sat May 18 23:44:17 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=fail; 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=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1586454282; cv=none; d=zohomail.com; s=zohoarc; b=NisXqYIRRzBl+UjmaA9DmfyH9WknDYhJvDcl1E0imKpNvMlspzPJteNgAfGGOnAUmnONtk2nrO0YAjLZrikXyaykYL4KedTlmUSEHMI8U4xCvaHsSbO/9YsJJIwXynEimhDCefVItHa2d/OduuUikIyjJAuGeYc+keSjWYdH6iY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1586454282; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9oSA8W/SfbM+lUUD53gbWLAOnZTi1X9SPyoosEQaqi4=; b=PjaPAmn1Hkf5n3SWWP9O4AHVbFJSCOQmya0u8quO7aphfgsuYIJhphhAsoziSf0287s3ct8MwI/Xb7mLNBPLhJzPQUOMMu0yFBWoYKcyRYRU6xfonyzJIVQ5gug8HO4FN+oxT3pMSf14MiXQkWfZ964h9qXYf45IhLnkvLkUE5w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; 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=fail header.from= (p=none 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 1586454282289996.2989909821786; Thu, 9 Apr 2020 10:44:42 -0700 (PDT) Received: from localhost ([::1]:53416 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMbEG-0000dt-VF for importer@patchew.org; Thu, 09 Apr 2020 13:44:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39539) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jMbCJ-0005oF-5r for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jMbC9-0006r0-8g for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:39 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:59949 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jMbC9-0006qS-5V for qemu-devel@nongnu.org; Thu, 09 Apr 2020 13:42:29 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-151-js8vZNHxOiyDZalCatj8cA-1; Thu, 09 Apr 2020 13:42:26 -0400 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7A0FC8017F3; Thu, 9 Apr 2020 17:42:25 +0000 (UTC) Received: from localhost (ovpn-114-141.ams2.redhat.com [10.36.114.141]) by smtp.corp.redhat.com (Postfix) with ESMTP id D04E911D2A4; Thu, 9 Apr 2020 17:42:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1586454148; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9oSA8W/SfbM+lUUD53gbWLAOnZTi1X9SPyoosEQaqi4=; b=fXjLTtvd3cpQ8T9Z6GQ8MyBjpkEtrHyjPs+oLd3ThP+PqVGh1h6isbmZ9SNJfwTRw0q7cs MxZaZewp4Slyf11OIVbcW8QxA432sgBMt7m49RAIIt/AjM//6lxe+x4mEcwv1E6sG/r93w A5Gu4rHD1Acx5XpxWkqk4cqxFL1soPo= X-MC-Unique: js8vZNHxOiyDZalCatj8cA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [PULL for-5.0 3/3] async: use explicit memory barriers Date: Thu, 9 Apr 2020 18:42:09 +0100 Message-Id: <20200409174209.321725-4-stefanha@redhat.com> In-Reply-To: <20200409174209.321725-1-stefanha@redhat.com> References: <20200409174209.321725-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Maydell , qemu-block@nongnu.org, Stefan Weil , Max Reitz , Stefan Hajnoczi , Ying Fang , Paolo Bonzini , Fam Zheng Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Paolo Bonzini When using C11 atomics, non-seqcst reads and writes do not participate in the total order of seqcst operations. In util/async.c and util/aio-posi= x.c, in particular, the pattern that we use write ctx->notify_me write bh->scheduled read bh->scheduled read ctx->notify_me if !bh->scheduled, sleep if ctx->notify_me, notify needs to use seqcst operations for both the write and the read. In general this is something that we do not want, because there can be many sources that are polled in addition to bottom halves. The alternative is to place a seqcst memory barrier between the write and the read. This also comes with a disadvantage, in that the memory barrier is implicit on strongly-ordered architectures and it wastes a few dozen clock cycles. Fortunately, ctx->notify_me is never written concurrently by two threads, so we can assert that and relax the writes to ctx->notify_me. The resulting solution works and performs well on both aarch64 and x86. Note that the atomic_set/atomic_read combination is not an atomic read-modify-write, and therefore it is even weaker than C11 ATOMIC_RELAXED; on x86, ATOMIC_RELAXED compiles to a locked operation. Analyzed-by: Ying Fang Signed-off-by: Paolo Bonzini Tested-by: Ying Fang Message-Id: <20200407140746.8041-6-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- util/aio-posix.c | 16 ++++++++++++++-- util/aio-win32.c | 17 ++++++++++++++--- util/async.c | 16 ++++++++++++---- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/util/aio-posix.c b/util/aio-posix.c index cd6cf0a4a9..c3613d299e 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -559,6 +559,11 @@ bool aio_poll(AioContext *ctx, bool blocking) int64_t timeout; int64_t start =3D 0; =20 + /* + * There cannot be two concurrent aio_poll calls for the same AioConte= xt (or + * an aio_poll concurrent with a GSource prepare/check/dispatch callba= ck). + * We rely on this below to avoid slow locked accesses to ctx->notify_= me. + */ assert(in_aio_context_home_thread(ctx)); =20 /* aio_notify can avoid the expensive event_notifier_set if @@ -569,7 +574,13 @@ bool aio_poll(AioContext *ctx, bool blocking) * so disable the optimization now. */ if (blocking) { - atomic_add(&ctx->notify_me, 2); + atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2); + /* + * Write ctx->notify_me before computing the timeout + * (reading bottom half flags, etc.). Pairs with + * smp_mb in aio_notify(). + */ + smp_mb(); } =20 qemu_lockcnt_inc(&ctx->list_lock); @@ -590,7 +601,8 @@ bool aio_poll(AioContext *ctx, bool blocking) } =20 if (blocking) { - atomic_sub(&ctx->notify_me, 2); + /* Finish the poll before clearing the flag. */ + atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me)= - 2); aio_notify_accept(ctx); } =20 diff --git a/util/aio-win32.c b/util/aio-win32.c index a23b9c364d..729d533faf 100644 --- a/util/aio-win32.c +++ b/util/aio-win32.c @@ -321,6 +321,12 @@ bool aio_poll(AioContext *ctx, bool blocking) int count; int timeout; =20 + /* + * There cannot be two concurrent aio_poll calls for the same AioConte= xt (or + * an aio_poll concurrent with a GSource prepare/check/dispatch callba= ck). + * We rely on this below to avoid slow locked accesses to ctx->notify_= me. + */ + assert(in_aio_context_home_thread(ctx)); progress =3D false; =20 /* aio_notify can avoid the expensive event_notifier_set if @@ -331,7 +337,13 @@ bool aio_poll(AioContext *ctx, bool blocking) * so disable the optimization now. */ if (blocking) { - atomic_add(&ctx->notify_me, 2); + atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2); + /* + * Write ctx->notify_me before computing the timeout + * (reading bottom half flags, etc.). Pairs with + * smp_mb in aio_notify(). + */ + smp_mb(); } =20 qemu_lockcnt_inc(&ctx->list_lock); @@ -364,8 +376,7 @@ bool aio_poll(AioContext *ctx, bool blocking) ret =3D WaitForMultipleObjects(count, events, FALSE, timeout); if (blocking) { assert(first); - assert(in_aio_context_home_thread(ctx)); - atomic_sub(&ctx->notify_me, 2); + atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify= _me) - 2); aio_notify_accept(ctx); } =20 diff --git a/util/async.c b/util/async.c index b94518b948..3165a28f2f 100644 --- a/util/async.c +++ b/util/async.c @@ -249,7 +249,14 @@ aio_ctx_prepare(GSource *source, gint *timeout) { AioContext *ctx =3D (AioContext *) source; =20 - atomic_or(&ctx->notify_me, 1); + atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) | 1); + + /* + * Write ctx->notify_me before computing the timeout + * (reading bottom half flags, etc.). Pairs with + * smp_mb in aio_notify(). + */ + smp_mb(); =20 /* We assume there is no timeout already supplied */ *timeout =3D qemu_timeout_ns_to_ms(aio_compute_timeout(ctx)); @@ -268,7 +275,8 @@ aio_ctx_check(GSource *source) QEMUBH *bh; BHListSlice *s; =20 - atomic_and(&ctx->notify_me, ~1); + /* Finish computing the timeout before clearing the flag. */ + atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) & ~= 1); aio_notify_accept(ctx); =20 QSLIST_FOREACH_RCU(bh, &ctx->bh_list, next) { @@ -411,10 +419,10 @@ LuringState *aio_get_linux_io_uring(AioContext *ctx) void aio_notify(AioContext *ctx) { /* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs - * with atomic_or in aio_ctx_prepare or atomic_add in aio_poll. + * with smp_mb in aio_ctx_prepare or aio_poll. */ smp_mb(); - if (ctx->notify_me) { + if (atomic_read(&ctx->notify_me)) { event_notifier_set(&ctx->notifier); atomic_mb_set(&ctx->notified, true); } --=20 2.25.1