From nobody Sun May 5 06:14:03 2024 Delivered-To: importer@patchew.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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1638379126626403.7619032277165; Wed, 1 Dec 2021 09:18:46 -0800 (PST) Received: from localhost ([::1]:40288 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msTFk-00048P-VN for importer@patchew.org; Wed, 01 Dec 2021 12:18:44 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48246) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzX-0000uI-3Z for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:59 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:58054) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzR-0001MP-W0 for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:58 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-211-cX2lUHQYMK29qlWKvWakZQ-1; Wed, 01 Dec 2021 12:01:50 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6DB3D801B23; Wed, 1 Dec 2021 17:01:24 +0000 (UTC) Received: from localhost (unknown [10.39.193.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id CA7015D6CF; Wed, 1 Dec 2021 17:01:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638378113; 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=IPFwV7nDfgqLumBpfYqLuM3JgL4F5aPh+HoVcMgOtxI=; b=NJgryQgOckvFSl8zVT+1pyu6l9+Wx2pbs6OOos0eVW+KtXrLMU1TYlIgfVHQzNapTqxt7p jQsKOetsG+tTZrelkeK4s2weF3ApZp3i3NcsGSDJxmvgYBGS/rSVOU7NoPyIc2OrioVTe7 Y1/9hJWHKRd/fOEx5LOcvLaZFFlXGyo= X-MC-Unique: cX2lUHQYMK29qlWKvWakZQ-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [RFC v2 1/4] tls: add macros for coroutine-safe TLS variables Date: Wed, 1 Dec 2021 17:01:17 +0000 Message-Id: <20211201170120.286139-2-stefanha@redhat.com> In-Reply-To: <20211201170120.286139-1-stefanha@redhat.com> References: <20211201170120.286139-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=stefanha@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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; Received-SPF: pass client-ip=170.10.129.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.716, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , fweimer@redhat.com, thuth@redhat.com, Daniel Berrange , qemu-block@nongnu.org, Richard Henderson , Stefan Hajnoczi , Paolo Bonzini , Fam Zheng , Warner Losh , sguelton@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1638379128547100001 Content-Type: text/plain; charset="utf-8" Compiler optimizations can cache TLS values across coroutine yield points, resulting in stale values from the previous thread when a coroutine is re-entered by a new thread. Serge Guelton developed an __attribute__((noinline)) wrapper and tested it with clang and gcc. I formatted his idea according to QEMU's coding style and wrote documentation. Richard Henderson developed an alternative approach that can be inlined by the compiler. This is included for architectures where we have inline assembly that determines the address of a TLS variable. These macros must be used instead of __thread from now on to prevent coroutine TLS bugs. Here is an x86_64 TLS variable access before this patch: mov %fs:-0x19c,%edx And here is the same access using Richard's approach: rdfsbase %rax # %fs contains the base address lea -0x1a8(%rax),%rax # -0x1a8 is the offset of our variable mov 0xc(%rax),%edx # here we access the TLS variable via %rax Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=3D1952483 Suggested-by: Serge Guelton Suggested-by: Richard Henderson Signed-off-by: Stefan Hajnoczi --- Richard's suggested code used a MOV instruction on x86_64 but we need LEA semantics. LEA doesn't support %fs so I switched to RDFSBASE+LEA. Otherwise Richard's approach is unchanged. --- include/qemu/coroutine-tls.h | 202 +++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 include/qemu/coroutine-tls.h diff --git a/include/qemu/coroutine-tls.h b/include/qemu/coroutine-tls.h new file mode 100644 index 0000000000..3158f9c0eb --- /dev/null +++ b/include/qemu/coroutine-tls.h @@ -0,0 +1,202 @@ +/* + * QEMU Thread Local Storage for coroutines + * + * Copyright Red Hat + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or l= ater. + * See the COPYING.LIB file in the top-level directory. + * + * It is forbidden to access Thread Local Storage in coroutines because + * compiler optimizations may cause values to be cached across coroutine + * re-entry. Coroutines can run in more than one thread through the course= of + * their life, leading bugs when stale TLS values from the wrong thread are + * used as a result of compiler optimization. + * + * An example is: + * + * ..code-block:: c + * :caption: A coroutine that may see the wrong TLS value + * + * static __thread AioContext *current_aio_context; + * ... + * static void coroutine_fn foo(void) + * { + * aio_notify(current_aio_context); + * qemu_coroutine_yield(); + * aio_notify(current_aio_context); // <-- may be stale after yieldi= ng! + * } + * + * This header provides macros for safely defining variables in Thread Loc= al + * Storage: + * + * ..code-block:: c + * :caption: A coroutine that safely uses TLS + * + * QEMU_DEFINE_STATIC_CO_TLS(AioContext *, current_aio_context) + * ... + * static void coroutine_fn foo(void) + * { + * aio_notify(get_current_aio_context()); + * qemu_coroutine_yield(); + * aio_notify(get_current_aio_context()); // <-- safe + * } + */ + +#ifndef QEMU_COROUTINE_TLS_H +#define QEMU_COROUTINE_TLS_H + +/* + * Two techniques are available to stop the compiler from caching TLS valu= es: + * 1. Accessor functions with __attribute__((noinline)). This is portable = but + * prevents inlining optimizations. + * 2. TLS address-of implemented as asm volatile so it can be inlined safe= ly. + * This enables inlining optimizations but requires architecture-specif= ic + * inline assembly. + */ +#if defined(__aarch64__) +#define QEMU_CO_TLS_ADDR(ret, var) \ + asm volatile("mrs %0, tpidr_el0\n\t" \ + "add %0, %0, #:tprel_hi12:"#var", lsl #12\n\t" \ + "add %0, %0, #:tprel_lo12_nc:"#var \ + : "=3Dr"(ret)) +#elif defined(__powerpc64__) +#define QEMU_CO_TLS_ADDR(ret, var) \ + asm volatile("addis %0,13,"#var"@tprel@ha\n\t" \ + "add %0,%0,"#var"@tprel@l" \ + : "=3Dr"(ret)) +#elif defined(__riscv) +#define QEMU_CO_TLS_ADDR(ret, var) \ + asm volatile("lui %0,%%tprel_hi("#var")\n\t" \ + "add %0,%0,%%tprel_add("#var")\n\t" \ + "addi %0,%0,%%tprel_lo("#var")" \ + : "=3Dr"(ret)) +#elif defined(__x86_64__) +#define QEMU_CO_TLS_ADDR(ret, var) \ + asm volatile("rdfsbase %0\n\t" \ + "lea "#var"@tpoff(%0), %0" : "=3Dr"(ret)) +#endif + +/** + * QEMU_DECLARE_CO_TLS: + * @type: the variable's C type + * @var: the variable name + * + * Declare an extern variable in Thread Local Storage from a header file: + * + * .. code-block:: c + * :caption: Declaring an extern variable in Thread Local Storage + * + * QEMU_DECLARE_CO_TLS(int, my_count) + * ... + * int c =3D get_my_count(); + * set_my_count(c + 1); + * *get_ptr_my_count() =3D 0; + * + * Use this instead of: + * + * .. code-block:: c + * :caption: Declaring a TLS variable using __thread + * + * extern __thread int my_count; + * ... + * int c =3D my_count; + * my_count =3D c + 1; + * *(&my_count) =3D 0; + */ +#ifdef QEMU_CO_TLS_ADDR +#define QEMU_DECLARE_CO_TLS(type, var) \ + extern __thread type co_tls_##var; \ + static inline type get_##var(void) \ + { type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); return *p; } \ + static inline void set_##var(type v) \ + { type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); *p =3D v; } \ + static inline type *get_ptr_##var(void) \ + { type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); return p; } +#else +#define QEMU_DECLARE_CO_TLS(type, var) \ + __attribute__((noinline)) type get_##var(void); \ + __attribute__((noinline)) void set_##var(type v); \ + __attribute__((noinline)) type *get_ptr_##var(void); +#endif + +/** + * QEMU_DEFINE_CO_TLS: + * @type: the variable's C type + * @var: the variable name + * + * Define an variable in Thread Local Storage that was previously declared= from + * a header file with QEMU_DECLARE_CO_TLS(): + * + * .. code-block:: c + * :caption: Defining a variable in Thread Local Storage + * + * QEMU_DEFINE_CO_TLS(int, my_count) + * + * Use this instead of: + * + * .. code-block:: c + * :caption: Defining a TLS variable using __thread + * + * __thread int my_count; + */ +#ifdef QEMU_CO_TLS_ADDR +#define QEMU_DEFINE_CO_TLS(type, var) \ + __thread type co_tls_##var; +#else +#define QEMU_DEFINE_CO_TLS(type, var) \ + static __thread type co_tls_##var; \ + type get_##var(void) { return co_tls_##var; } \ + void set_##var(type v) { co_tls_##var =3D v; } \ + type *get_ptr_##var(void) { return &co_tls_##var; } +#endif + +/** + * QEMU_DEFINE_STATIC_CO_TLS: + * @type: the variable's C type + * @var: the variable name + * + * Define a static variable in Thread Local Storage: + * + * .. code-block:: c + * :caption: Defining a static variable in Thread Local Storage + * + * QEMU_DEFINE_STATIC_CO_TLS(int, my_count) + * ... + * int c =3D get_my_count(); + * set_my_count(c + 1); + * *get_ptr_my_count() =3D 0; + * + * Use this instead of: + * + * .. code-block:: c + * :caption: Defining a static TLS variable using __thread + * + * static __thread int my_count; + * ... + * int c =3D my_count; + * my_count =3D c + 1; + * *(&my_count) =3D 0; + */ +#ifdef QEMU_CO_TLS_ADDR +#define QEMU_DEFINE_STATIC_CO_TLS(type, var) \ + __thread type co_tls_##var; \ + static inline type get_##var(void) \ + { type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); return *p; } \ + static inline void set_##var(type v) \ + { type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); *p =3D v; } \ + static inline type *get_ptr_##var(void) \ + { type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); return p; } +#else +#define QEMU_DEFINE_STATIC_CO_TLS(type, var) \ + static __thread type co_tls_##var; \ + static __attribute__((noinline, unused)) type get_##var(void) \ + { return co_tls_##var; } \ + static __attribute__((noinline, unused)) void set_##var(type v) \ + { co_tls_##var =3D v; } \ + static __attribute__((noinline, unused)) type *get_ptr_##var(void) \ + { return &co_tls_##var; } +#endif + +#endif /* QEMU_COROUTINE_TLS_H */ --=20 2.33.1 From nobody Sun May 5 06:14:03 2024 Delivered-To: importer@patchew.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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1638378422802248.98274946002505; Wed, 1 Dec 2021 09:07:02 -0800 (PST) Received: from localhost ([::1]:46792 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msT4O-00060V-DS for importer@patchew.org; Wed, 01 Dec 2021 12:07:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48142) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzS-0000bP-VL for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:54 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:37283) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzQ-0001L8-0i for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:53 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-461-RlwB8DHAPKmZkrHq8nprHg-1; Wed, 01 Dec 2021 12:01:48 -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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id F094564168; Wed, 1 Dec 2021 17:01:25 +0000 (UTC) Received: from localhost (unknown [10.39.193.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9768D45D67; Wed, 1 Dec 2021 17:01:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638378110; 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=mG/4/c6JahFepUvT35nbK2boHd5C0dHum/iIdDDWEzU=; b=derxCbGmrnFIqU/z40VAv1NgLccqp+gyNEe8SCpDRCNQVK2uJMMDlOKKD8X0dKuVRUAgQU mf9cQmdcTQH8m1yQTA2Nut8myUH338hvc38wcF2WCmsdb/5Uv2uJz5rk7+8oanAlCiFGhI rX57yj8w4D+2X62sBqV45AN6YX9/bHU= X-MC-Unique: RlwB8DHAPKmZkrHq8nprHg-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [RFC v2 2/4] util/async: replace __thread with QEMU TLS macros Date: Wed, 1 Dec 2021 17:01:18 +0000 Message-Id: <20211201170120.286139-3-stefanha@redhat.com> In-Reply-To: <20211201170120.286139-1-stefanha@redhat.com> References: <20211201170120.286139-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=stefanha@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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; Received-SPF: pass client-ip=170.10.129.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.716, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , fweimer@redhat.com, thuth@redhat.com, Daniel Berrange , qemu-block@nongnu.org, Richard Henderson , Stefan Hajnoczi , Paolo Bonzini , Fam Zheng , Warner Losh , sguelton@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1638378425006100001 Content-Type: text/plain; charset="utf-8" QEMU TLS macros must be used to make TLS variables safe with coroutines. Signed-off-by: Stefan Hajnoczi --- util/async.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/util/async.c b/util/async.c index 6f6717a34b..ddd9f24419 100644 --- a/util/async.c +++ b/util/async.c @@ -32,6 +32,7 @@ #include "qemu/rcu_queue.h" #include "block/raw-aio.h" #include "qemu/coroutine_int.h" +#include "qemu/coroutine-tls.h" #include "trace.h" =20 /***********************************************************/ @@ -669,12 +670,13 @@ void aio_context_release(AioContext *ctx) qemu_rec_mutex_unlock(&ctx->lock); } =20 -static __thread AioContext *my_aiocontext; +QEMU_DEFINE_STATIC_CO_TLS(AioContext *, my_aiocontext) =20 AioContext *qemu_get_current_aio_context(void) { - if (my_aiocontext) { - return my_aiocontext; + AioContext *ctx =3D get_my_aiocontext(); + if (ctx) { + return ctx; } if (qemu_mutex_iothread_locked()) { /* Possibly in a vCPU thread. */ @@ -685,6 +687,6 @@ AioContext *qemu_get_current_aio_context(void) =20 void qemu_set_current_aio_context(AioContext *ctx) { - assert(!my_aiocontext); - my_aiocontext =3D ctx; + assert(!get_my_aiocontext()); + set_my_aiocontext(ctx); } --=20 2.33.1 From nobody Sun May 5 06:14:03 2024 Delivered-To: importer@patchew.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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1638378552492716.8682569456007; Wed, 1 Dec 2021 09:09:12 -0800 (PST) Received: from localhost ([::1]:52132 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msT6V-0001DM-Dm for importer@patchew.org; Wed, 01 Dec 2021 12:09:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48186) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzT-0000iR-Se for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:55 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:32072) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzQ-0001Lc-An for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:55 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-126-51MShBKgMmiKMmZiwiD1-w-1; Wed, 01 Dec 2021 12:01:49 -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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7714F1937FFA; Wed, 1 Dec 2021 17:01:27 +0000 (UTC) Received: from localhost (unknown [10.39.193.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1DAD119811; Wed, 1 Dec 2021 17:01:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638378111; 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=1zwI4SSAGseqe99BJ4tH/CN4/F2g0U2EsjU4hUPD/cc=; b=dk99n+ppIj3QfD+Lyg6qrWruWRlrQ/4pwlA4ssJbM6Qlyt6XqRElUJ4JvWh9gB9yy5k98a ToLkHSY3XKO20B1YQD+ko55ECUJKwvJpSLU+RENUxZoXj1V3DBRP/lfAaV+siQtZK09+nz CcAFEijPmr7CZzx43RRU4UOYG992+Rw= X-MC-Unique: 51MShBKgMmiKMmZiwiD1-w-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [RFC v2 3/4] rcu: use coroutine TLS macros Date: Wed, 1 Dec 2021 17:01:19 +0000 Message-Id: <20211201170120.286139-4-stefanha@redhat.com> In-Reply-To: <20211201170120.286139-1-stefanha@redhat.com> References: <20211201170120.286139-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=stefanha@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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; Received-SPF: pass client-ip=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.716, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , fweimer@redhat.com, thuth@redhat.com, Daniel Berrange , qemu-block@nongnu.org, Richard Henderson , Stefan Hajnoczi , Paolo Bonzini , Fam Zheng , Warner Losh , sguelton@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1638378554221100001 Content-Type: text/plain; charset="utf-8" RCU may be used from coroutines. Standard __thread variables cannot be used by coroutines. Use the coroutine TLS macros instead. Signed-off-by: Stefan Hajnoczi --- include/qemu/rcu.h | 7 ++++--- tests/unit/rcutorture.c | 10 +++++----- tests/unit/test-rcu-list.c | 4 ++-- util/rcu.c | 10 +++++----- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index e69efbd47f..b063c6fde8 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -29,6 +29,7 @@ #include "qemu/atomic.h" #include "qemu/notify.h" #include "qemu/sys_membarrier.h" +#include "qemu/coroutine-tls.h" =20 #ifdef __cplusplus extern "C" { @@ -76,11 +77,11 @@ struct rcu_reader_data { NotifierList force_rcu; }; =20 -extern __thread struct rcu_reader_data rcu_reader; +QEMU_DECLARE_CO_TLS(struct rcu_reader_data, rcu_reader) =20 static inline void rcu_read_lock(void) { - struct rcu_reader_data *p_rcu_reader =3D &rcu_reader; + struct rcu_reader_data *p_rcu_reader =3D get_ptr_rcu_reader(); unsigned ctr; =20 if (p_rcu_reader->depth++ > 0) { @@ -96,7 +97,7 @@ static inline void rcu_read_lock(void) =20 static inline void rcu_read_unlock(void) { - struct rcu_reader_data *p_rcu_reader =3D &rcu_reader; + struct rcu_reader_data *p_rcu_reader =3D get_ptr_rcu_reader(); =20 assert(p_rcu_reader->depth !=3D 0); if (--p_rcu_reader->depth > 0) { diff --git a/tests/unit/rcutorture.c b/tests/unit/rcutorture.c index de6f649058..495a4e6f42 100644 --- a/tests/unit/rcutorture.c +++ b/tests/unit/rcutorture.c @@ -122,7 +122,7 @@ static void *rcu_read_perf_test(void *arg) =20 rcu_register_thread(); =20 - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); qatomic_inc(&nthreadsrunning); while (goflag =3D=3D GOFLAG_INIT) { g_usleep(1000); @@ -148,7 +148,7 @@ static void *rcu_update_perf_test(void *arg) =20 rcu_register_thread(); =20 - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); qatomic_inc(&nthreadsrunning); while (goflag =3D=3D GOFLAG_INIT) { g_usleep(1000); @@ -253,7 +253,7 @@ static void *rcu_read_stress_test(void *arg) =20 rcu_register_thread(); =20 - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); while (goflag =3D=3D GOFLAG_INIT) { g_usleep(1000); } @@ -304,7 +304,7 @@ static void *rcu_update_stress_test(void *arg) struct rcu_stress *cp =3D qatomic_read(&rcu_stress_current); =20 rcu_register_thread(); - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); =20 while (goflag =3D=3D GOFLAG_INIT) { g_usleep(1000); @@ -347,7 +347,7 @@ static void *rcu_fake_update_stress_test(void *arg) { rcu_register_thread(); =20 - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); while (goflag =3D=3D GOFLAG_INIT) { g_usleep(1000); } diff --git a/tests/unit/test-rcu-list.c b/tests/unit/test-rcu-list.c index 49641e1936..64b81ae058 100644 --- a/tests/unit/test-rcu-list.c +++ b/tests/unit/test-rcu-list.c @@ -171,7 +171,7 @@ static void *rcu_q_reader(void *arg) =20 rcu_register_thread(); =20 - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); qatomic_inc(&nthreadsrunning); while (qatomic_read(&goflag) =3D=3D GOFLAG_INIT) { g_usleep(1000); @@ -206,7 +206,7 @@ static void *rcu_q_updater(void *arg) long long n_removed_local =3D 0; struct list_element *el, *prev_el; =20 - *(struct rcu_reader_data **)arg =3D &rcu_reader; + *(struct rcu_reader_data **)arg =3D get_ptr_rcu_reader(); qatomic_inc(&nthreadsrunning); while (qatomic_read(&goflag) =3D=3D GOFLAG_INIT) { g_usleep(1000); diff --git a/util/rcu.c b/util/rcu.c index c91da9f137..b6d6c71cff 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -65,7 +65,7 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) /* Written to only by each individual reader. Read by both the reader and = the * writers. */ -__thread struct rcu_reader_data rcu_reader; +QEMU_DEFINE_CO_TLS(struct rcu_reader_data, rcu_reader) =20 /* Protected by rcu_registry_lock. */ typedef QLIST_HEAD(, rcu_reader_data) ThreadList; @@ -355,23 +355,23 @@ void drain_call_rcu(void) =20 void rcu_register_thread(void) { - assert(rcu_reader.ctr =3D=3D 0); + assert(get_ptr_rcu_reader()->ctr =3D=3D 0); qemu_mutex_lock(&rcu_registry_lock); - QLIST_INSERT_HEAD(®istry, &rcu_reader, node); + QLIST_INSERT_HEAD(®istry, get_ptr_rcu_reader(), node); qemu_mutex_unlock(&rcu_registry_lock); } =20 void rcu_unregister_thread(void) { qemu_mutex_lock(&rcu_registry_lock); - QLIST_REMOVE(&rcu_reader, node); + QLIST_REMOVE(get_ptr_rcu_reader(), node); qemu_mutex_unlock(&rcu_registry_lock); } =20 void rcu_add_force_rcu_notifier(Notifier *n) { qemu_mutex_lock(&rcu_registry_lock); - notifier_list_add(&rcu_reader.force_rcu, n); + notifier_list_add(&get_ptr_rcu_reader()->force_rcu, n); qemu_mutex_unlock(&rcu_registry_lock); } =20 --=20 2.33.1 From nobody Sun May 5 06:14:03 2024 Delivered-To: importer@patchew.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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1638378633072572.2465556907024; Wed, 1 Dec 2021 09:10:33 -0800 (PST) Received: from localhost ([::1]:56012 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msT7n-0003on-Ps for importer@patchew.org; Wed, 01 Dec 2021 12:10:31 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48222) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzV-0000nz-DZ for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:57 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:27688) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msSzR-0001Lz-1c for qemu-devel@nongnu.org; Wed, 01 Dec 2021 12:01:57 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-576-Hw-YXYTPPui8UCe4dnfrsA-1; Wed, 01 Dec 2021 12:01:51 -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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id F1C3483DEB4; Wed, 1 Dec 2021 17:01:28 +0000 (UTC) Received: from localhost (unknown [10.39.193.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9825860C0F; Wed, 1 Dec 2021 17:01:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638378112; 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=SXKxVIQfgEzUB9nZN8iSnmE7twiawSE6uxMym8yZJpU=; b=f70iKCUPcPx+rU9+yD6cHP7xVwtDNAvW33QRP5sEQI93ZNAqI6oOmCi+k2HuF9/IrwmhUz yebc+i7U3KdU6H6b9bsZhPKKV2RcenkovqssweWtwWUaC2vE3ow2wgZXENZeVRkB/TUrYo kpuzP7d7gOlzvl1AX0RytFdPwY0T5hQ= X-MC-Unique: Hw-YXYTPPui8UCe4dnfrsA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Subject: [RFC v2 4/4] cpus: use coroutine TLS macros for iothread_locked Date: Wed, 1 Dec 2021 17:01:20 +0000 Message-Id: <20211201170120.286139-5-stefanha@redhat.com> In-Reply-To: <20211201170120.286139-1-stefanha@redhat.com> References: <20211201170120.286139-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=stefanha@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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; Received-SPF: pass client-ip=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.716, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , fweimer@redhat.com, thuth@redhat.com, Daniel Berrange , qemu-block@nongnu.org, Richard Henderson , Stefan Hajnoczi , Paolo Bonzini , Fam Zheng , Warner Losh , sguelton@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1638378633708100001 Content-Type: text/plain; charset="utf-8" qemu_mutex_iothread_locked() may be used from coroutines. Standard __thread variables cannot be used by coroutines. Use the coroutine TLS macros instead. Signed-off-by: Stefan Hajnoczi --- softmmu/cpus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 071085f840..b02d3211e1 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -474,11 +474,11 @@ bool qemu_in_vcpu_thread(void) return current_cpu && qemu_cpu_is_self(current_cpu); } =20 -static __thread bool iothread_locked =3D false; +QEMU_DEFINE_STATIC_CO_TLS(bool, iothread_locked) =20 bool qemu_mutex_iothread_locked(void) { - return iothread_locked; + return get_iothread_locked(); } =20 /* @@ -491,13 +491,13 @@ void qemu_mutex_lock_iothread_impl(const char *file, = int line) =20 g_assert(!qemu_mutex_iothread_locked()); bql_lock(&qemu_global_mutex, file, line); - iothread_locked =3D true; + set_iothread_locked(true); } =20 void qemu_mutex_unlock_iothread(void) { g_assert(qemu_mutex_iothread_locked()); - iothread_locked =3D false; + set_iothread_locked(false); qemu_mutex_unlock(&qemu_global_mutex); } =20 --=20 2.33.1