From patchwork Wed Dec 25 05:44:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920614 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 70031E7718D for ; Wed, 25 Dec 2024 05:45:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKC2-000716-GC; Wed, 25 Dec 2024 00:44:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKC0-00070j-VI for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:24 -0500 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKBz-0008Hr-5g for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:24 -0500 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2ef89dbd8eeso4429834a91.0 for ; Tue, 24 Dec 2024 21:44:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105462; x=1735710262; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=b7RpjOm/DRzNyiYtGsOFcg7Tby9rNOjO2BBVF9kv5qg=; b=ZbubS6a2P/9VicKMcLQKuC0qHJ0RXTJAWdohjkPZG2yafMGE0/SB+Ufq+TJnDFMDsM EQmfZiNSJrp6yD+thi/UK96dF/w2QDdOEJtndZHSZdcihMlG57UgFXuuSUDwuv63dBOT ncFi7h8Djs+NsmBja3Ngf34rbrdsU+2oVrC9mJdDd7ClWnWd2tKyUa8UuDXUxTOwpxXh /eD/CpSmLnizmVgh90T+H6ohXwcFjvZ5gXkctA2P3+4wxcG0uNAWkCmhGjOstrhNNf56 CV4y3fvXtJLeUuFvn3HZBcayKhvoAZz/W+vaps6IdGIgpw8piJZpOrwsJOhVaBW/OuhC 9/0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105462; x=1735710262; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=b7RpjOm/DRzNyiYtGsOFcg7Tby9rNOjO2BBVF9kv5qg=; b=KIq1aNAPiy9LaTvr51FCzbSemYVT1vbSLs/IAjKuZcw5m8hNiDJzSjDTb3i4aLhZxP sdKJq1rz39i9UoTuW92ZokjLSD+zr1UnwmK8ToRXPDLxrnXy2StmI3XGvKTdD+B0xBeG xlju0kZK1YC7+nCbAVTJthMdpKh+tecCdYKRsUGOVZc2JdHrQ2AU6NVPPiePa9nEXtT2 I6qU2omutkhSUArALTIq1ceD6eO0ArDs3Nwny7grytycRUEPMMlMt/LxEM3Y72VsAw8O zWKa9Jd/Ab92OdlkvKR5nP/WxqXPxa27mcMfsA7LnI236iZ4w77UkbRYSpxpua3JnwTY j8CA== X-Forwarded-Encrypted: i=1; AJvYcCW+ASUxQxS085a0EQRpGfiysbmBodRJYv3RRUoRa8vaw/mYHk9dTUxav7iJFsWf2G8M3ZcfVO5oGOJ8@nongnu.org X-Gm-Message-State: AOJu0YxWqmsqldyTbD+ZgF2kXnzxUczMK/KFQAprN1cdyc/AoOubR9Lt CLnaMXvJ7U69+xjzjavin6uad/jWnAvtYO2GL3KI/Wz4czKhzAHGAoDDSLjkb3U= X-Gm-Gg: ASbGncsBYYyO4+NBkC9dO1pwjJcNBfH+yWvQIQK0vLHoOXxsSfHGacBFgfCUrot1ae6 DSW6o08BqgaqfE0SWxSnt3aruMs6uVpnkIK7Q+v/54ape2y5rMdU0ftC/KyfXVTVQW7HBsLvA5X d8L5/vbjifXmSoZAQcdO2BW/KGyH2ToNf60m/C2N2YTsyjvH1PNjFAv17wGV2XhhTG+k1JPDFyh UCGH9XaUJDONv0Z9S2NG5FwH9jQvogmRGOXgOycc6neIMzPVTB1Xf/M+ljh X-Google-Smtp-Source: AGHT+IGa2l6dwZz0j525YolHjw3IJJJPuYTmsAG3f7lXGhmQOcauWO7gJ255qeBXcHHq2uDXWiRqHQ== X-Received: by 2002:a17:90b:54d0:b0:2ee:c918:cd60 with SMTP id 98e67ed59e1d1-2f452e4a7f6mr28970252a91.20.1735105461854; Tue, 24 Dec 2024 21:44:21 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id 98e67ed59e1d1-2f2ee26b131sm14653894a91.44.2024.12.24.21.44.19 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:21 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:13 +0900 Subject: [PATCH 1/8] futex: Check value after qemu_futex_wait() MIME-Version: 1.0 Message-Id: <20241225-event-v1-1-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org futex(2) - Linux manual page https://man7.org/linux/man-pages/man2/futex.2.html > Note that a wake-up can also be caused by common futex usage patterns > in unrelated code that happened to have previously used the futex > word's memory location (e.g., typical futex-based implementations of > Pthreads mutexes can cause this under some conditions). Therefore, > callers should always conservatively assume that a return value of 0 > can mean a spurious wake-up, and use the futex word's value (i.e., > the user-space synchronization scheme) to decide whether to continue > to block or not. Signed-off-by: Akihiko Odaki --- include/qemu/futex.h | 9 +++++++++ tests/unit/test-aio-multithread.c | 4 +++- util/qemu-thread-posix.c | 28 ++++++++++++++++------------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/include/qemu/futex.h b/include/qemu/futex.h index 91ae88966e12..f57774005330 100644 --- a/include/qemu/futex.h +++ b/include/qemu/futex.h @@ -24,6 +24,15 @@ static inline void qemu_futex_wake(void *f, int n) qemu_futex(f, FUTEX_WAKE, n, NULL, NULL, 0); } +/* + * Note that a wake-up can also be caused by common futex usage patterns in + * unrelated code that happened to have previously used the futex word's + * memory location (e.g., typical futex-based implementations of Pthreads + * mutexes can cause this under some conditions). Therefore, callers should + * always conservatively assume that it is a spurious wake-up, and use the futex + * word's value (i.e., the user-space synchronization scheme) to decide whether + * to continue to block or not. + */ static inline void qemu_futex_wait(void *f, unsigned val) { while (qemu_futex(f, FUTEX_WAIT, (int) val, NULL, NULL, 0)) { diff --git a/tests/unit/test-aio-multithread.c b/tests/unit/test-aio-multithread.c index 08d4570ccb14..8c2e41545a29 100644 --- a/tests/unit/test-aio-multithread.c +++ b/tests/unit/test-aio-multithread.c @@ -305,7 +305,9 @@ static void mcs_mutex_lock(void) prev = qatomic_xchg(&mutex_head, id); if (prev != -1) { qatomic_set(&nodes[prev].next, id); - qemu_futex_wait(&nodes[id].locked, 1); + while (qatomic_read(&nodes[id].locked) == 1) { + qemu_futex_wait(&nodes[id].locked, 1); + } } } diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index b2e26e21205b..eade5311d175 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -428,17 +428,21 @@ void qemu_event_wait(QemuEvent *ev) assert(ev->initialized); - /* - * qemu_event_wait must synchronize with qemu_event_set even if it does - * not go down the slow path, so this load-acquire is needed that - * synchronizes with the first memory barrier in qemu_event_set(). - * - * If we do go down the slow path, there is no requirement at all: we - * might miss a qemu_event_set() here but ultimately the memory barrier in - * qemu_futex_wait() will ensure the check is done correctly. - */ - value = qatomic_load_acquire(&ev->value); - if (value != EV_SET) { + while (true) { + /* + * qemu_event_wait must synchronize with qemu_event_set even if it does + * not go down the slow path, so this load-acquire is needed that + * synchronizes with the first memory barrier in qemu_event_set(). + * + * If we do go down the slow path, there is no requirement at all: we + * might miss a qemu_event_set() here but ultimately the memory barrier + * in qemu_futex_wait() will ensure the check is done correctly. + */ + value = qatomic_load_acquire(&ev->value); + if (value == EV_SET) { + break; + } + if (value == EV_FREE) { /* * Leave the event reset and tell qemu_event_set that there are @@ -452,7 +456,7 @@ void qemu_event_wait(QemuEvent *ev) * like the load above. */ if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) { - return; + break; } } From patchwork Wed Dec 25 05:44:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920622 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A3767E7718B for ; Wed, 25 Dec 2024 05:45:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKC8-00071w-3w; Wed, 25 Dec 2024 00:44:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKC5-00071T-NY for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:29 -0500 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKC3-0008Jd-Nh for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:29 -0500 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-21619108a6bso54441715ad.3 for ; Tue, 24 Dec 2024 21:44:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105466; x=1735710266; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=zAt3HH9n1Q4e0VDMLF4qELhaKJyL8RlrkODaMjrBVSc=; b=oSwxILHiylHH25z+5EbR/a792Cc6+KEgpnLWEB2mg1fyz2FsFZBxQZXR9ViVXt2Q0O gCeZzKF4BZ+Ajpk0g85g/ys7ODVchqptt/S/Yy5J9zIssydZXm46KjKjNu7y1es7lgVl p97WknmYtmE/zoPaYo2xzw+Ozssy8WAf8E8m+RCXKn9PD7iIMvRvGAHlrHliLRyIhzPd LPAzXjpfadWwiMwZaubGNlxz4zK5sXGprXicYSP7F6qtkP8GdLUDS7o0WVpdDAQN9JIS EHAs60dzlAoJh8lCDnu0t/De6NG0inV4opz13QHdDJIFqHLw/8f2h7CHYQ+lGBBxT3Uf 18yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105466; x=1735710266; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zAt3HH9n1Q4e0VDMLF4qELhaKJyL8RlrkODaMjrBVSc=; b=Z7w/dqqBGNNwFBOElaHCE+WudBe8qZ7gHC561UbuQX8LzLl178zgu+ILQk0jIgdwCE uXE5KGb6XShC+5XWOnKXVdLIY+ZycM4dTuQ0OoLSQKy+Xc/0GfMoPM1pnbJmnrrgbYY5 Zi0H18ikF/quGSjFPvBu/kEnvxtBfCMdOAxZkrLBHBd/pAne6MSAypkWuNNx/1tdLrSl DgO/fQjQPI9/izTUrQcyrnOAoUo6EUMC/1kERpSqufIO7jIg9aEo9gsqDLdtcGTMopLG FjjFAU6uai/ChOA3RFldk8H2R/F/zURqcPrRoQ0zQKNf0Tqh1p28eeiJU3kO42b+4yvD o09Q== X-Forwarded-Encrypted: i=1; AJvYcCVRpR/MdiFy7J5FY7RXjkMLqexFEqK6qg+VD479oXRikZFvr88UupP1+3xudDe3sL/kNJZMkgnWbYTS@nongnu.org X-Gm-Message-State: AOJu0YwpbhR66xjsA+AQxzZPz/OctdCMw5SqGYddI7UBe60Tv6UWJaSx +t3m8ziqDZuQp7idw59UR6KEdlP/0tfoNMxEIIRgYwdmNtxcR7o1/Tp0qBhSGyc= X-Gm-Gg: ASbGnctgB1Ak8+Hoph3KwZmZCmVU+1nCvKkYokVOo3O+aNca7puf53jI/7YMlspKm7H C5CAWBthOBxegcB5KGIEBejGaKM4+XyGXyBb8Stj9fYLfpIBsmlEg7EEj5LsL+KFTf78nhFjTj5 9dZQACFNEKbgQnUt+hFRq3pJNME453WBtJACFNcVz7qpiuVAO7Thhk67Es/iEnVdyxlBHYh6AeH VXwLI1LGNgE9SR4swi7qojiuB3iLG5MPLkOTBUFbrzp8n0id6shXHL9m2H/ X-Google-Smtp-Source: AGHT+IEC15ohGaoIdaRd2slbCHL8fkV2+MJGVukl9AVQbPL1+v3VFYd+I/HTkIqlUH5UDU/0Xvcfvg== X-Received: by 2002:a05:6a20:d49b:b0:1e0:c7cf:bc1f with SMTP id adf61e73a8af0-1e5e0447f12mr30538920637.9.1735105466177; Tue, 24 Dec 2024 21:44:26 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-72aad8dd180sm10923398b3a.109.2024.12.24.21.44.24 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:25 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:14 +0900 Subject: [PATCH 2/8] futex: Support Windows MIME-Version: 1.0 Message-Id: <20241225-event-v1-2-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::631; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x631.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Windows supports futex-like APIs since Windows 8 and Windows Server 2012. Signed-off-by: Akihiko Odaki --- meson.build | 2 ++ include/qemu/futex.h | 52 ++++++++++++++++++++++++++++++--------- tests/unit/test-aio-multithread.c | 2 +- util/lockcnt.c | 2 +- util/qemu-thread-posix.c | 4 +-- util/meson.build | 2 +- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/meson.build b/meson.build index e0b880e4e138..083b6c45d240 100644 --- a/meson.build +++ b/meson.build @@ -798,11 +798,13 @@ emulator_link_args = [] midl = not_found widl = not_found pathcch = not_found +synchronization = not_found host_dsosuf = '.so' if host_os == 'windows' midl = find_program('midl', required: false) widl = find_program('widl', required: false) pathcch = cc.find_library('pathcch') + synchronization = cc.find_library('Synchronization') socket = cc.find_library('ws2_32') winmm = cc.find_library('winmm') diff --git a/include/qemu/futex.h b/include/qemu/futex.h index f57774005330..c22d756021c9 100644 --- a/include/qemu/futex.h +++ b/include/qemu/futex.h @@ -1,5 +1,5 @@ /* - * Wrappers around Linux futex syscall + * Wrappers around Linux futex syscall and similar * * Copyright Red Hat, Inc. 2017 * @@ -11,28 +11,36 @@ * */ +/* + * Note that a wake-up can also be caused by common futex usage patterns in + * unrelated code that happened to have previously used the futex word's + * memory location (e.g., typical futex-based implementations of Pthreads + * mutexes can cause this under some conditions). Therefore, qemu_futex_wait() + * callers should always conservatively assume that it is a spurious wake-up, + * and use the futex word's value (i.e., the user-space synchronization scheme) + * to decide whether to continue to block or not. + */ + #ifndef QEMU_FUTEX_H #define QEMU_FUTEX_H +#define HAVE_FUTEX + +#ifdef CONFIG_LINUX #include #include #define qemu_futex(...) syscall(__NR_futex, __VA_ARGS__) -static inline void qemu_futex_wake(void *f, int n) +static inline void qemu_futex_wake_all(void *f) { - qemu_futex(f, FUTEX_WAKE, n, NULL, NULL, 0); + qemu_futex(f, FUTEX_WAKE, INT_MAX, NULL, NULL, 0); } -/* - * Note that a wake-up can also be caused by common futex usage patterns in - * unrelated code that happened to have previously used the futex word's - * memory location (e.g., typical futex-based implementations of Pthreads - * mutexes can cause this under some conditions). Therefore, callers should - * always conservatively assume that it is a spurious wake-up, and use the futex - * word's value (i.e., the user-space synchronization scheme) to decide whether - * to continue to block or not. - */ +static inline void qemu_futex_wake_single(void *f) +{ + qemu_futex(f, FUTEX_WAKE, 1, NULL, NULL, 0); +} static inline void qemu_futex_wait(void *f, unsigned val) { while (qemu_futex(f, FUTEX_WAIT, (int) val, NULL, NULL, 0)) { @@ -46,5 +54,25 @@ static inline void qemu_futex_wait(void *f, unsigned val) } } } +#elif defined(CONFIG_WIN32) +#include + +static inline void qemu_futex_wake_all(void *f) +{ + WakeByAddressAll(f); +} + +static inline void qemu_futex_wake_single(void *f) +{ + WakeByAddressSingle(f); +} + +static inline void qemu_futex_wait(void *f, unsigned val) +{ + WaitOnAddress(f, &val, sizeof(val), INFINITE); +} +#else +#undef HAVE_FUTEX +#endif #endif /* QEMU_FUTEX_H */ diff --git a/tests/unit/test-aio-multithread.c b/tests/unit/test-aio-multithread.c index 8c2e41545a29..0ead6bf34ad1 100644 --- a/tests/unit/test-aio-multithread.c +++ b/tests/unit/test-aio-multithread.c @@ -330,7 +330,7 @@ static void mcs_mutex_unlock(void) /* Wake up the next in line. */ next = qatomic_read(&nodes[id].next); nodes[next].locked = 0; - qemu_futex_wake(&nodes[next].locked, 1); + qemu_futex_wake_single(&nodes[next].locked); } static void test_multi_fair_mutex_entry(void *opaque) diff --git a/util/lockcnt.c b/util/lockcnt.c index d07c6cc5cee4..ca27d8e61a5c 100644 --- a/util/lockcnt.c +++ b/util/lockcnt.c @@ -106,7 +106,7 @@ static bool qemu_lockcnt_cmpxchg_or_wait(QemuLockCnt *lockcnt, int *val, static void lockcnt_wake(QemuLockCnt *lockcnt) { trace_lockcnt_futex_wake(lockcnt); - qemu_futex_wake(&lockcnt->count, 1); + qemu_futex_wake_single(&lockcnt->count); } void qemu_lockcnt_inc(QemuLockCnt *lockcnt) diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index eade5311d175..13459e44c768 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -345,7 +345,7 @@ static inline void qemu_futex_wait(QemuEvent *ev, unsigned val) /* Valid transitions: * - free->set, when setting the event - * - busy->set, when setting the event, followed by qemu_futex_wake + * - busy->set, when setting the event, followed by qemu_futex_wake_all * - set->free, when resetting the event * - free->busy, when waiting * @@ -400,7 +400,7 @@ void qemu_event_set(QemuEvent *ev) smp_mb__after_rmw(); if (old == EV_BUSY) { /* There were waiters, wake them up. */ - qemu_futex_wake(ev, INT_MAX); + qemu_futex_wake_all(ev); } } } diff --git a/util/meson.build b/util/meson.build index 5d8bef98912a..da5b49f1ea82 100644 --- a/util/meson.build +++ b/util/meson.build @@ -25,7 +25,7 @@ else util_ss.add(files('event_notifier-win32.c')) util_ss.add(files('oslib-win32.c')) util_ss.add(files('qemu-thread-win32.c')) - util_ss.add(winmm, pathcch) + util_ss.add(winmm, pathcch, synchronization) endif util_ss.add(when: linux_io_uring, if_true: files('fdmon-io_uring.c')) if glib_has_gslice From patchwork Wed Dec 25 05:44:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920615 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6D038E7718B for ; Wed, 25 Dec 2024 05:45:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKCA-00072J-TR; Wed, 25 Dec 2024 00:44:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKC8-000727-Up for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:33 -0500 Received: from mail-pl1-x62f.google.com ([2607:f8b0:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKC7-0008LI-B2 for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:32 -0500 Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-21649a7bcdcso60944535ad.1 for ; Tue, 24 Dec 2024 21:44:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105470; x=1735710270; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=PYcRFVNaBbHYspn9XDdEp8ak1VIr/hP0YWEzEZgYuj4=; b=g+3zM5iDvcuSNDXreBc9VH86Mqmnh+I+69ozCOZOeYWp2yvlsncdc7A3Q1DGX/e5Mr qLnbTizpG2LiKznT4yc3mR6f8+Pi7jmO8CE1XmdqdLdAAQQassvMLfHucyXyRl7auz2s o1swaZrPc8g5kMPpDVjxVSy3AuCLw9xEBeViwPPX6wTYP6jJ1iFACaxwEaGstLPN3rtc PW6dV2ZHL4wGLitxHV0VaffJEGRRNZ1MXe/7hO0bGCGBH8GFRPNFCpJ9U5VjQ6DskG6r 3iZ9uJDLwheVRTASJrzQ+XRIHW0mMGW1w8e6L/z8320mxWZZDwVKQuQdWI7vB20Rzuft nSIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105470; x=1735710270; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PYcRFVNaBbHYspn9XDdEp8ak1VIr/hP0YWEzEZgYuj4=; b=pONF7RZXs3eMU77RWS27DOfu/TTG1ZzkgQekrQpc90J72rAiF7FNsMIEeaap/92KQE 8VkGP64mB7830rq8kcw/N1MFAfHAIhN2UGOkRRHq3lc2lLzQdBNQHvx0zLM8lqyjIHNN shvEQJGaBFBo9Jt0lV0bmq3mnIXkGABfmhL2sB2WqK7sPRYtHOLXzdPzXjBgDYBT5hvM PxcqW1RhJhtUH93DPu6xZw2CNjYkcS6C/4eH9RgHspxPB0VdAF9dBnjrUSBDtRK8PtRL wSDD+lNxXCLVu2fSZ9gOMviv9e/y0XVc/LJYoAU9FRiJy2y+OPXFUeK1Rs1nLteNosC7 gMtA== X-Forwarded-Encrypted: i=1; AJvYcCUQllYJ8kECvna1KillMns9v3GV7pg7n1Pa/kPXRKJksRhLlfZxlN/jDQda/+VIgY57fCY7u7EKIs4g@nongnu.org X-Gm-Message-State: AOJu0YzFLSVO6BMyv420ICZ5Qf9tZ3OSxl6migSQJhJVi1pf+2zp8p6U tzAIZF58sCeRiA+9rSRjFwoG5jJCAh8j+wVlyqakSfG2V4wNL1awxnqOVxVkqxgYFFtnN0GEgwV 0g50= X-Gm-Gg: ASbGncvljZ2ooGNWv4SJSV6HWjYC/f8xRkzVDGth9kmES0TN2P0wZ4AgiCvOXFn9bVk P+Q/LSSNpFnlPwmHjuwqyxSGoQX+sZczs177gcg3Nw3ePT8x2dKitn23vqyUfW0SlMyq9PrFjjm 1eDcXZAtpG+WnRl6K7oFfdsUXexE3JksbMNEJ4QLkip8wtPTbw/6caYEURcOKGsx1qk4ybcjv1S tjTCqjQDtClX7B+HU1UauVq5aM659ait/SUAXajbRFHaVJUDiqB8n18QnfM X-Google-Smtp-Source: AGHT+IHXeDoyUqcHHFAsb3MfjDdYSpHlqL0+sCQwhI7BH1vH3qex9nH45BL1yrtyPZxVuEEhq2rxyg== X-Received: by 2002:a17:902:d2ca:b0:216:32c4:f7f5 with SMTP id d9443c01a7336-219e6ea19a7mr212205245ad.19.1735105469927; Tue, 24 Dec 2024 21:44:29 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-219dc96e764sm98329955ad.62.2024.12.24.21.44.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:29 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:15 +0900 Subject: [PATCH 3/8] qemu-thread: Avoid futex abstraction for non-Linux MIME-Version: 1.0 Message-Id: <20241225-event-v1-3-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::62f; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62f.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org qemu-thread used to abstract pthread primitives into futex for the QemuEvent implementation of POSIX systems other than Linux. However, this abstraction has one key difference: unlike futex, pthread primitives require an explicit destruction, and it must be ordered after wait and wake operations. It would be easier to perform destruction if a wait operation ensures the corresponding wake operation finishes as POSIX semaphore does, but that requires to protect state accesses in qemu_event_set() and qemu_event_wait() with a mutex. On the other hand, real futex does not need such a protection but needs complex barrier and atomic operations before wait and wake operations instead. Add special implementations of qemu_event_set() and qemu_event_wait() using pthread primitives. qemu_event_wait() will ensure qemu_event_set() finishes, and these functions will avoid complex barrier and atomic operations. Signed-off-by: Akihiko Odaki --- util/qemu-thread-posix.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 13459e44c768..805cac444f15 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -319,28 +319,6 @@ void qemu_sem_wait(QemuSemaphore *sem) #ifdef __linux__ #include "qemu/futex.h" -#else -static inline void qemu_futex_wake(QemuEvent *ev, int n) -{ - assert(ev->initialized); - pthread_mutex_lock(&ev->lock); - if (n == 1) { - pthread_cond_signal(&ev->cond); - } else { - pthread_cond_broadcast(&ev->cond); - } - pthread_mutex_unlock(&ev->lock); -} - -static inline void qemu_futex_wait(QemuEvent *ev, unsigned val) -{ - assert(ev->initialized); - pthread_mutex_lock(&ev->lock); - if (ev->value == val) { - pthread_cond_wait(&ev->cond, &ev->lock); - } - pthread_mutex_unlock(&ev->lock); -} #endif /* Valid transitions: @@ -363,7 +341,7 @@ static inline void qemu_futex_wait(QemuEvent *ev, unsigned val) void qemu_event_init(QemuEvent *ev, bool init) { -#ifndef __linux__ +#ifndef CONFIG_LINUX pthread_mutex_init(&ev->lock, NULL); pthread_cond_init(&ev->cond, NULL); #endif @@ -376,7 +354,7 @@ void qemu_event_destroy(QemuEvent *ev) { assert(ev->initialized); ev->initialized = false; -#ifndef __linux__ +#ifndef CONFIG_LINUX pthread_mutex_destroy(&ev->lock); pthread_cond_destroy(&ev->cond); #endif @@ -386,6 +364,7 @@ void qemu_event_set(QemuEvent *ev) { assert(ev->initialized); +#ifdef CONFIG_LINUX /* * Pairs with both qemu_event_reset() and qemu_event_wait(). * @@ -403,6 +382,12 @@ void qemu_event_set(QemuEvent *ev) qemu_futex_wake_all(ev); } } +#else + pthread_mutex_lock(&ev->lock); + qatomic_set(&ev->value, EV_SET); + pthread_cond_broadcast(&ev->cond); + pthread_mutex_unlock(&ev->lock); +#endif } void qemu_event_reset(QemuEvent *ev) @@ -424,10 +409,9 @@ void qemu_event_reset(QemuEvent *ev) void qemu_event_wait(QemuEvent *ev) { - unsigned value; - assert(ev->initialized); +#ifdef CONFIG_LINUX while (true) { /* * qemu_event_wait must synchronize with qemu_event_set even if it does @@ -438,7 +422,7 @@ void qemu_event_wait(QemuEvent *ev) * might miss a qemu_event_set() here but ultimately the memory barrier * in qemu_futex_wait() will ensure the check is done correctly. */ - value = qatomic_load_acquire(&ev->value); + unsigned value = qatomic_load_acquire(&ev->value); if (value == EV_SET) { break; } @@ -467,6 +451,13 @@ void qemu_event_wait(QemuEvent *ev) */ qemu_futex_wait(ev, EV_BUSY); } +#else + pthread_mutex_lock(&ev->lock); + if (qatomic_read(&ev->value) != EV_SET) { + pthread_cond_wait(&ev->cond, &ev->lock); + } + pthread_mutex_unlock(&ev->lock); +#endif } static __thread NotifierList thread_exit; From patchwork Wed Dec 25 05:44:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A7F7BE7718D for ; Wed, 25 Dec 2024 05:45:36 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKCF-000737-It; Wed, 25 Dec 2024 00:44:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKCE-00072s-4S for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:38 -0500 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKCB-0008Mn-KB for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:37 -0500 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-2164b1f05caso59523035ad.3 for ; Tue, 24 Dec 2024 21:44:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105474; x=1735710274; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=y0dJk2V+rE4PujnuLWGLjchvT5Ur3ihlFfD3AC8SUs8=; b=Ax2MAgmFAWuM9MzAZGn0cc2y5TAy8PcLbA4CZL4RdUbw3cICwxMOqhSaCBG65Hq3yq inA/VQjF35/Olt39rEUEs+p/EK3TTVmCg/UKLUSVWA9hD+7ivXYiOdP0tRWNM+0eiZCx yVW0DE2h3D81lCGC0B4kkmIDFpbzeyxM9BKuLddPXG0kN8YLmXZ2/Vy+NMYYtUx/Nfxz n2lRV00PC73vjwnx0Pi9sN/gO2LKeF+hKCqA7UnaP7lacRvQbzEhaU5HJL4+AZ2SjguK e0+EjmTqiLe0Wo5Y/2s270bQE9dW2WZoy0aWuE/ciXdFJH5tLdwYiq9UNEk4IJqZ0CCt DhJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105474; x=1735710274; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=y0dJk2V+rE4PujnuLWGLjchvT5Ur3ihlFfD3AC8SUs8=; b=nLQoMP0PUcBi1GzIAHtOzTk/71YREHfI/6A0nc4fsVyWRH0yz73oFNsPzLHlp6iain F2Tb3JT3MxGGzLYVVOUXPkIT6tucPCNwYJdWkifDK8O5artwgzu5NCeSxaLvRg8it3SO T7yKlcgZ3p4mbf13V2O0tu+VpR1zQ731fTbjcQm+SSa5z0qp/VLbmmBmUvFPOd0qKdJy 9M796XRvS+8fzGFUaPAt9CwY99b24XF7DbqZBFXZxDstUGj3dymoDJgny8tiKOCwpGx1 mjJXDlu7IvAwW6Q8U5zU1Mi6mVYgE1h8f5hEZiDmpE1/fQylU4iEfaVguRYlvbW3NDxY kMpw== X-Forwarded-Encrypted: i=1; AJvYcCUIMHUh04DgESM4bBDrqWMkmx/p0Qz8vC7T4BkR3BmXdZy33GrY1PSrqOhK5XsksEyp3qIV/RNf+wIl@nongnu.org X-Gm-Message-State: AOJu0YzqV8m+x7wtPfzmzNdbNYx296CpByBYAXwtnK+UjaAcEkXuq4uX LWMpXUnn6E4NsIAhjQCYQgbkjSoNDF+zT9rdoUkxLVmgb8rxCpWA981+vimHaX4= X-Gm-Gg: ASbGncsV2UFgxaFBVe8qb7luLWw9m2JnUueU1X3viQekdDN0zDVr8QGbSeN6ch7oY+G vV2QNdljIf9PmKOUZS5hcPw1UeKeAtnrV64aepRJMhP6Bdsff3fYCiwfhEbhdn47mWfwYz/GmKT uAxUh8tKtNoGbrb/ghitKagRkwFewu4jRm+SUoDNNxl9PvVqr3upx7oeQgeeHtYu6RRHm6cHkdo KiV6bS59aAXSUPRPwaTiuVgCwFXpFAwtdYAdN6FhO/056HMUKwDg15ik7qg X-Google-Smtp-Source: AGHT+IG9LWbwE54hM1Et3LXyIJywSwZz3wR5TVBhCUKKhwcINmJKOb3eQpD3N9ByDWlzhgbzfjjYLA== X-Received: by 2002:a17:902:d582:b0:216:5e6e:68ca with SMTP id d9443c01a7336-219e6f26685mr311413835ad.49.1735105474184; Tue, 24 Dec 2024 21:44:34 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-219dc962d5fsm98473145ad.38.2024.12.24.21.44.31 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:33 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:16 +0900 Subject: [PATCH 4/8] qemu-thread: Use futex for QemuEvent on Windows MIME-Version: 1.0 Message-Id: <20241225-event-v1-4-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Use the futex-based implementation of QemuEvent on Windows to remove code duplication and remove the overhead of event object construction and destruction. Signed-off-by: Akihiko Odaki --- include/qemu/thread-posix.h | 9 --- include/qemu/thread-win32.h | 6 -- include/qemu/thread.h | 11 +++- util/event.c | 144 ++++++++++++++++++++++++++++++++++++++++++++ util/qemu-thread-posix.c | 143 ------------------------------------------- util/qemu-thread-win32.c | 129 --------------------------------------- util/meson.build | 1 + 7 files changed, 155 insertions(+), 288 deletions(-) diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h index 5f2f3d1386bc..758808b705e4 100644 --- a/include/qemu/thread-posix.h +++ b/include/qemu/thread-posix.h @@ -32,15 +32,6 @@ struct QemuSemaphore { unsigned int count; }; -struct QemuEvent { -#ifndef __linux__ - pthread_mutex_t lock; - pthread_cond_t cond; -#endif - unsigned value; - bool initialized; -}; - struct QemuThread { pthread_t thread; }; diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h index d95af4498fc9..da9e7322990c 100644 --- a/include/qemu/thread-win32.h +++ b/include/qemu/thread-win32.h @@ -28,12 +28,6 @@ struct QemuSemaphore { bool initialized; }; -struct QemuEvent { - int value; - HANDLE event; - bool initialized; -}; - typedef struct QemuThreadData QemuThreadData; struct QemuThread { QemuThreadData *data; diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 7eba27a70493..cab58a14404d 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -4,13 +4,22 @@ #include "qemu/processor.h" #include "qemu/atomic.h" #include "qemu/clang-tsa.h" +#include "qemu/futex.h" typedef struct QemuCond QemuCond; typedef struct QemuSemaphore QemuSemaphore; -typedef struct QemuEvent QemuEvent; typedef struct QemuLockCnt QemuLockCnt; typedef struct QemuThread QemuThread; +typedef struct QemuEvent { +#ifndef HAVE_FUTEX + pthread_mutex_t lock; + pthread_cond_t cond; +#endif + unsigned value; + bool initialized; +} QemuEvent; + #ifdef _WIN32 #include "qemu/thread-win32.h" #else diff --git a/util/event.c b/util/event.c new file mode 100644 index 000000000000..34ac7a08d0bf --- /dev/null +++ b/util/event.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "qemu/thread.h" + +/* + * Valid transitions: + * - free->set, when setting the event + * - busy->set, when setting the event, followed by qemu_futex_wake_all + * - set->free, when resetting the event + * - free->busy, when waiting + * + * set->busy does not happen (it can be observed from the outside but + * it really is set->free->busy). + * + * busy->free provably cannot happen; to enforce it, the set->free transition + * is done with an OR, which becomes a no-op if the event has concurrently + * transitioned to free or busy. + */ + +#define EV_SET 0 +#define EV_FREE 1 +#define EV_BUSY -1 + +void qemu_event_init(QemuEvent *ev, bool init) +{ +#ifndef HAVE_FUTEX + pthread_mutex_init(&ev->lock, NULL); + pthread_cond_init(&ev->cond, NULL); +#endif + + ev->value = (init ? EV_SET : EV_FREE); + ev->initialized = true; +} + +void qemu_event_destroy(QemuEvent *ev) +{ + assert(ev->initialized); + ev->initialized = false; +#ifndef HAVE_FUTEX + pthread_mutex_destroy(&ev->lock); + pthread_cond_destroy(&ev->cond); +#endif +} + +void qemu_event_set(QemuEvent *ev) +{ + assert(ev->initialized); + +#ifdef HAVE_FUTEX + /* + * Pairs with both qemu_event_reset() and qemu_event_wait(). + * + * qemu_event_set has release semantics, but because it *loads* + * ev->value we need a full memory barrier here. + */ + smp_mb(); + if (qatomic_read(&ev->value) != EV_SET) { + int old = qatomic_xchg(&ev->value, EV_SET); + + /* Pairs with memory barrier in kernel futex_wait system call. */ + smp_mb__after_rmw(); + if (old == EV_BUSY) { + /* There were waiters, wake them up. */ + qemu_futex_wake_all(ev); + } + } +#else + pthread_mutex_lock(&ev->lock); + qatomic_set(&ev->value, EV_SET); + pthread_cond_broadcast(&ev->cond); + pthread_mutex_unlock(&ev->lock); +#endif +} + +void qemu_event_reset(QemuEvent *ev) +{ + assert(ev->initialized); + + /* + * If there was a concurrent reset (or even reset+wait), + * do nothing. Otherwise change EV_SET->EV_FREE. + */ + qatomic_or(&ev->value, EV_FREE); + + /* + * Order reset before checking the condition in the caller. + * Pairs with the first memory barrier in qemu_event_set(). + */ + smp_mb__after_rmw(); +} + +void qemu_event_wait(QemuEvent *ev) +{ + assert(ev->initialized); + +#ifdef HAVE_FUTEX + while (true) { + /* + * qemu_event_wait must synchronize with qemu_event_set even if it does + * not go down the slow path, so this load-acquire is needed that + * synchronizes with the first memory barrier in qemu_event_set(). + * + * If we do go down the slow path, there is no requirement at all: we + * might miss a qemu_event_set() here but ultimately the memory barrier + * in qemu_futex_wait() will ensure the check is done correctly. + */ + unsigned value = qatomic_load_acquire(&ev->value); + if (value == EV_SET) { + break; + } + + if (value == EV_FREE) { + /* + * Leave the event reset and tell qemu_event_set that there are + * waiters. No need to retry, because there cannot be a concurrent + * busy->free transition. After the CAS, the event will be either + * set or busy. + * + * This cmpxchg doesn't have particular ordering requirements if it + * succeeds (moving the store earlier can only cause + * qemu_event_set() to issue _more_ wakeups), the failing case needs + * acquire semantics like the load above. + */ + if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) { + break; + } + } + + /* + * This is the final check for a concurrent set, so it does need + * a smp_mb() pairing with the second barrier of qemu_event_set(). + * The barrier is inside the FUTEX_WAIT system call. + */ + qemu_futex_wait(ev, EV_BUSY); + } +#else + pthread_mutex_lock(&ev->lock); + if (qatomic_read(&ev->value) != EV_SET) { + pthread_cond_wait(&ev->cond, &ev->lock); + } + pthread_mutex_unlock(&ev->lock); +#endif +} diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 805cac444f15..ba725444ba63 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -317,149 +317,6 @@ void qemu_sem_wait(QemuSemaphore *sem) qemu_mutex_unlock(&sem->mutex); } -#ifdef __linux__ -#include "qemu/futex.h" -#endif - -/* Valid transitions: - * - free->set, when setting the event - * - busy->set, when setting the event, followed by qemu_futex_wake_all - * - set->free, when resetting the event - * - free->busy, when waiting - * - * set->busy does not happen (it can be observed from the outside but - * it really is set->free->busy). - * - * busy->free provably cannot happen; to enforce it, the set->free transition - * is done with an OR, which becomes a no-op if the event has concurrently - * transitioned to free or busy. - */ - -#define EV_SET 0 -#define EV_FREE 1 -#define EV_BUSY -1 - -void qemu_event_init(QemuEvent *ev, bool init) -{ -#ifndef CONFIG_LINUX - pthread_mutex_init(&ev->lock, NULL); - pthread_cond_init(&ev->cond, NULL); -#endif - - ev->value = (init ? EV_SET : EV_FREE); - ev->initialized = true; -} - -void qemu_event_destroy(QemuEvent *ev) -{ - assert(ev->initialized); - ev->initialized = false; -#ifndef CONFIG_LINUX - pthread_mutex_destroy(&ev->lock); - pthread_cond_destroy(&ev->cond); -#endif -} - -void qemu_event_set(QemuEvent *ev) -{ - assert(ev->initialized); - -#ifdef CONFIG_LINUX - /* - * Pairs with both qemu_event_reset() and qemu_event_wait(). - * - * qemu_event_set has release semantics, but because it *loads* - * ev->value we need a full memory barrier here. - */ - smp_mb(); - if (qatomic_read(&ev->value) != EV_SET) { - int old = qatomic_xchg(&ev->value, EV_SET); - - /* Pairs with memory barrier in kernel futex_wait system call. */ - smp_mb__after_rmw(); - if (old == EV_BUSY) { - /* There were waiters, wake them up. */ - qemu_futex_wake_all(ev); - } - } -#else - pthread_mutex_lock(&ev->lock); - qatomic_set(&ev->value, EV_SET); - pthread_cond_broadcast(&ev->cond); - pthread_mutex_unlock(&ev->lock); -#endif -} - -void qemu_event_reset(QemuEvent *ev) -{ - assert(ev->initialized); - - /* - * If there was a concurrent reset (or even reset+wait), - * do nothing. Otherwise change EV_SET->EV_FREE. - */ - qatomic_or(&ev->value, EV_FREE); - - /* - * Order reset before checking the condition in the caller. - * Pairs with the first memory barrier in qemu_event_set(). - */ - smp_mb__after_rmw(); -} - -void qemu_event_wait(QemuEvent *ev) -{ - assert(ev->initialized); - -#ifdef CONFIG_LINUX - while (true) { - /* - * qemu_event_wait must synchronize with qemu_event_set even if it does - * not go down the slow path, so this load-acquire is needed that - * synchronizes with the first memory barrier in qemu_event_set(). - * - * If we do go down the slow path, there is no requirement at all: we - * might miss a qemu_event_set() here but ultimately the memory barrier - * in qemu_futex_wait() will ensure the check is done correctly. - */ - unsigned value = qatomic_load_acquire(&ev->value); - if (value == EV_SET) { - break; - } - - if (value == EV_FREE) { - /* - * Leave the event reset and tell qemu_event_set that there are - * waiters. No need to retry, because there cannot be a concurrent - * busy->free transition. After the CAS, the event will be either - * set or busy. - * - * This cmpxchg doesn't have particular ordering requirements if it - * succeeds (moving the store earlier can only cause qemu_event_set() - * to issue _more_ wakeups), the failing case needs acquire semantics - * like the load above. - */ - if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) { - break; - } - } - - /* - * This is the final check for a concurrent set, so it does need - * a smp_mb() pairing with the second barrier of qemu_event_set(). - * The barrier is inside the FUTEX_WAIT system call. - */ - qemu_futex_wait(ev, EV_BUSY); - } -#else - pthread_mutex_lock(&ev->lock); - if (qatomic_read(&ev->value) != EV_SET) { - pthread_cond_wait(&ev->cond, &ev->lock); - } - pthread_mutex_unlock(&ev->lock); -#endif -} - static __thread NotifierList thread_exit; /* diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index a7fe3cc345f0..ca2e0b512e26 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -231,135 +231,6 @@ void qemu_sem_wait(QemuSemaphore *sem) } } -/* Wrap a Win32 manual-reset event with a fast userspace path. The idea - * is to reset the Win32 event lazily, as part of a test-reset-test-wait - * sequence. Such a sequence is, indeed, how QemuEvents are used by - * RCU and other subsystems! - * - * Valid transitions: - * - free->set, when setting the event - * - busy->set, when setting the event, followed by SetEvent - * - set->free, when resetting the event - * - free->busy, when waiting - * - * set->busy does not happen (it can be observed from the outside but - * it really is set->free->busy). - * - * busy->free provably cannot happen; to enforce it, the set->free transition - * is done with an OR, which becomes a no-op if the event has concurrently - * transitioned to free or busy (and is faster than cmpxchg). - */ - -#define EV_SET 0 -#define EV_FREE 1 -#define EV_BUSY -1 - -void qemu_event_init(QemuEvent *ev, bool init) -{ - /* Manual reset. */ - ev->event = CreateEvent(NULL, TRUE, TRUE, NULL); - ev->value = (init ? EV_SET : EV_FREE); - ev->initialized = true; -} - -void qemu_event_destroy(QemuEvent *ev) -{ - assert(ev->initialized); - ev->initialized = false; - CloseHandle(ev->event); -} - -void qemu_event_set(QemuEvent *ev) -{ - assert(ev->initialized); - - /* - * Pairs with both qemu_event_reset() and qemu_event_wait(). - * - * qemu_event_set has release semantics, but because it *loads* - * ev->value we need a full memory barrier here. - */ - smp_mb(); - if (qatomic_read(&ev->value) != EV_SET) { - int old = qatomic_xchg(&ev->value, EV_SET); - - /* Pairs with memory barrier after ResetEvent. */ - smp_mb__after_rmw(); - if (old == EV_BUSY) { - /* There were waiters, wake them up. */ - SetEvent(ev->event); - } - } -} - -void qemu_event_reset(QemuEvent *ev) -{ - assert(ev->initialized); - - /* - * If there was a concurrent reset (or even reset+wait), - * do nothing. Otherwise change EV_SET->EV_FREE. - */ - qatomic_or(&ev->value, EV_FREE); - - /* - * Order reset before checking the condition in the caller. - * Pairs with the first memory barrier in qemu_event_set(). - */ - smp_mb__after_rmw(); -} - -void qemu_event_wait(QemuEvent *ev) -{ - unsigned value; - - assert(ev->initialized); - - /* - * qemu_event_wait must synchronize with qemu_event_set even if it does - * not go down the slow path, so this load-acquire is needed that - * synchronizes with the first memory barrier in qemu_event_set(). - * - * If we do go down the slow path, there is no requirement at all: we - * might miss a qemu_event_set() here but ultimately the memory barrier in - * qemu_futex_wait() will ensure the check is done correctly. - */ - value = qatomic_load_acquire(&ev->value); - if (value != EV_SET) { - if (value == EV_FREE) { - /* - * Here the underlying kernel event is reset, but qemu_event_set is - * not yet going to call SetEvent. However, there will be another - * check for EV_SET below when setting EV_BUSY. At that point it - * is safe to call WaitForSingleObject. - */ - ResetEvent(ev->event); - - /* - * It is not clear whether ResetEvent provides this barrier; kernel - * APIs (KeResetEvent/KeClearEvent) do not. Better safe than sorry! - */ - smp_mb(); - - /* - * Leave the event reset and tell qemu_event_set that there are - * waiters. No need to retry, because there cannot be a concurrent - * busy->free transition. After the CAS, the event will be either - * set or busy. - */ - if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) { - return; - } - } - - /* - * ev->value is now EV_BUSY. Since we didn't observe EV_SET, - * qemu_event_set() must observe EV_BUSY and call SetEvent(). - */ - WaitForSingleObject(ev->event, INFINITE); - } -} - struct QemuThreadData { /* Passed to win32_start_routine. */ void *(*start_routine)(void *); diff --git a/util/meson.build b/util/meson.build index da5b49f1ea82..6d23df3d25d2 100644 --- a/util/meson.build +++ b/util/meson.build @@ -33,6 +33,7 @@ if glib_has_gslice endif util_ss.add(files('defer-call.c')) util_ss.add(files('envlist.c', 'path.c', 'module.c')) +util_ss.add(files('event.c')) util_ss.add(files('host-utils.c')) util_ss.add(files('bitmap.c', 'bitops.c')) util_ss.add(files('fifo8.c')) From patchwork Wed Dec 25 05:44:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 30CBBE7718D for ; Wed, 25 Dec 2024 05:45:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKCH-00073V-Oy; Wed, 25 Dec 2024 00:44:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKCG-00073N-IP for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:40 -0500 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKCE-0008O9-UW for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:40 -0500 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-2163b0c09afso59677085ad.0 for ; Tue, 24 Dec 2024 21:44:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105478; x=1735710278; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=DdexgsTRx5ghvnxfUSfjxB7Ao/P1TQJISnBHx9RM6RI=; b=zc6svIf0dHsW/ZOjqre8j8k8dIpc+SWYuGSiSSeTpC00unxPyHCJFjuVXFv2o466YM QxaHloBAOZZteoyAPZxtboKHPYZF1bfgIbhjWPbqcxg5zr5+rm9IzWpTUxDTBoDx+Pp5 PVIUR2ENhBD4h8D8+SXFQeWUcGIhNYV50jkWIlDn5S4mBOzyhrXfGqzrhnPmyZCJpQ/7 Dgj33H5zadcY6dfkkUbcYqqo89BEMSxlSJ5LRJRHjEFPNuBaxAnKifzctjmQyYBES863 NVf7I3Vr6E15SMqAQmJXt4g5KamGCzn1N8amOnFHZOq0vjOZIA9kzQpDZZ0aX85w97PR ZRoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105478; x=1735710278; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DdexgsTRx5ghvnxfUSfjxB7Ao/P1TQJISnBHx9RM6RI=; b=EvOcSYg54TOloS/xPmAlFnIlY551ogdrtxICz4/k8Wqwe7Il0CnGr8W+udmc9Sjo5h Bek0zVH169K+09nkEQdgjYg0FqTWiX66Pkhwt/mW3S8InW/ZfmfMrs0U6LlHlzJzf/uw bwGyAbu03KJ5Rd3gCJJvwdpz3I+CzD58wb3FpOQTfIIvAh+rnqcIcBojxSGKdrZ0YoJk OUCpGc4lFMER1XttO6js8Dm57ozC/hDWCOlFXCTc6J+LwaMggo2d9/2jji0nRcuFGk1s ecJ2yYADvJ6yitGHlgyNRC+rP4JU9HXEhYE8G6o+YP66JNflSGLENMAY+Ug20JD85Sbb Zd1A== X-Forwarded-Encrypted: i=1; AJvYcCUNK/8QI153xtnFYY5KTUKvpeMzQcZszJRkunrwtenOsNIoufnbF6bun9YGB4plX8pD7DOGXfINZuVM@nongnu.org X-Gm-Message-State: AOJu0YytFvLHOCe94PZenhKjWox7E6sZyokRwUyG23KPG4BwLf1nvjI5 0tinOpSljnbRK8DxjdmTgsN57nK6X3rdCTWN6Y1b0UxYQd3jskuTYJH2GXmHWas= X-Gm-Gg: ASbGncvbdmKgeXazGfLcvSE+3IlPxgAGt93Yte5WEWgyzOL196Iluxfk7vGTouXIyKJ xmELf6hRW/+VbRQVZ3swhPQw1zQZmmVZHg90vQ/QMS+Y3cPu0oXRC5FqjkwdQBHPGQGkM0bmqmX pim6SwcWnWq4uzSiqW7bctwtlfp73+mhaoaXKFEw+RtwAK6nEw1KwCoPbOA1JIxIOahVEtw3hfR jyfBU0ett2dP3PIJcMiT5khoDG7fxyQ9zC9iJKo3+nqEKfUjv8PAKXD5OIu X-Google-Smtp-Source: AGHT+IE+XjUSs2O3Mg7yEeDLL5J5FOg1irk5lCkvlDyw4bBe2jtSD4B4YQqQtlFzGFkxTAnJNflBGA== X-Received: by 2002:a17:902:fc50:b0:215:b8c6:338a with SMTP id d9443c01a7336-219e6e85ccemr284555585ad.4.1735105477745; Tue, 24 Dec 2024 21:44:37 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-219dc962cddsm98695455ad.48.2024.12.24.21.44.35 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:37 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:17 +0900 Subject: [PATCH 5/8] qemu-thread: Use futex if available for QemuLockCnt MIME-Version: 1.0 Message-Id: <20241225-event-v1-5-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::631; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x631.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This unlocks the futex-based implementation of QemuLockCnt to Windows. Signed-off-by: Akihiko Odaki --- include/qemu/lockcnt.h | 2 +- util/lockcnt.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/qemu/lockcnt.h b/include/qemu/lockcnt.h index f4b62a3f7011..5a2800e3f182 100644 --- a/include/qemu/lockcnt.h +++ b/include/qemu/lockcnt.h @@ -17,7 +17,7 @@ typedef struct QemuLockCnt QemuLockCnt; struct QemuLockCnt { -#ifndef CONFIG_LINUX +#ifndef HAVE_FUTEX QemuMutex mutex; #endif unsigned count; diff --git a/util/lockcnt.c b/util/lockcnt.c index ca27d8e61a5c..92c9f8ceca88 100644 --- a/util/lockcnt.c +++ b/util/lockcnt.c @@ -12,10 +12,11 @@ #include "qemu/atomic.h" #include "trace.h" -#ifdef CONFIG_LINUX -#include "qemu/futex.h" +#ifdef HAVE_FUTEX -/* On Linux, bits 0-1 are a futex-based lock, bits 2-31 are the counter. +/* + * When futex is available, bits 0-1 are a futex-based lock, bits 2-31 are the + * counter. * For the mutex algorithm see Ulrich Drepper's "Futexes Are Tricky" (ok, * this is not the most relaxing citation I could make...). It is similar * to mutex2 in the paper. From patchwork Wed Dec 25 05:44:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920618 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BF9A7E7718B for ; Wed, 25 Dec 2024 05:45:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKCL-00074Q-RG; Wed, 25 Dec 2024 00:44:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKCL-00074I-6H for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:45 -0500 Received: from mail-pl1-x62f.google.com ([2607:f8b0:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKCJ-0008Pl-Gi for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:44 -0500 Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-2166022c5caso53717465ad.2 for ; Tue, 24 Dec 2024 21:44:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105482; x=1735710282; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=I2zxAtTii6E1s8gPn0imFrR7S0+oZT+AgctpC/QrvNY=; b=f7piiHsSuHOeAtzTtz8UU7CuIUKRfAlR7fCWy2eUU03u81G5wxW3BU6Bqjs7jPaUbi bC+Uk4LjO6pp9V/7iMN9a1I/d8yukgHWevth3jmFQQwSYCcVObyf3WzxESo8IT41oBGd DjIX5aIvzZqleNEDfx0IU7qFIEguZCKLIVbNFThcQ3swfKmke+YT2h4cgK6ONegk76dV 7If/u+TjxXzMmgKVnTKrMa5webvXggjF7CrH+rCGmqz9JuIJwcLNRks06dQucWQM6VJi tU1tGkK1y7F/VMoiMj6LYJx2dJxbXPQYIBTAfZOYhltoQyE/6sdFBzLnv+r9q1DAB4HU iNMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105482; x=1735710282; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=I2zxAtTii6E1s8gPn0imFrR7S0+oZT+AgctpC/QrvNY=; b=Bny1W6q1q1JPG+sLHu2AlBsfOFb3S30rm8TLylnRtD9ojhig8Lh469dlHmy4RXicCk XFsoBgMnHCCBaec83x3mFANaLl8We8g8eYDgh0NarEZQvUA39w5K4LvfeG6FnmK8PA0s QGzwCSjFkro3Zl0XkSk/CXe6Sry62LT8GW+aSn2ExzOqPceirkeQZvMcyMQz4FMlNSBo FxQpbLqKdxXO4JhfOjltLNhlWo0pPZkzZU9MjKkKHou/IMg8QCH0d3z28/nb5AvUxA0Z 62SSflRsJxITXD8qsnRY2xnZ6WgXCxadQdeSVENaavzs50aGIrzKJJw9vNPAvLBWMD5W A7mA== X-Forwarded-Encrypted: i=1; AJvYcCXuPdDbOy8/eHeOJJMjGGOkrZjvxUSveB2UnKg4njO5lZcnGsKtpay92kLhtg63xHIggnO87xGV2uZn@nongnu.org X-Gm-Message-State: AOJu0Yx6qRwrXK4zSvGIL+ONFI56868CF0rt9tmLJTazFHsnQanOc63v +muJAaUzRaX/w4GueRf13PbotmbozLH5GlZMtN8WXqkWLUI+RvkXB1nkSmrk/xw= X-Gm-Gg: ASbGncuMOVA0vHwalnfZb6422J0SI40vt2fO+TRYXwmJwR//NZfnO8eniLoF+5Sdzja hzvCqzje1RoU5fwsPhD8WUx4af6H/mqoNqP2h4Lag++KI3nFYatP0NzlVTrq+9rgO/rBrbmEdec 9gXz3MbrIxUQJlWLDsnOKQT6KIcD4OUimLAtpYkGo7af9soyfadiremrWJZfN5mBsIm/QwYHo6O 3qkF7ZlOxvlx18YYfyY2kwrLHDehooFNxVy4Oxjcz9eyzM7atyNmCdd453S X-Google-Smtp-Source: AGHT+IFMDWkKJ7l87KHA8cPNVTPzxOu2iDtFqcCdXahboFCjjNvWnMCxoebG85Ghxztx7R40H33bbw== X-Received: by 2002:a05:6a21:2d05:b0:1cf:27bf:8e03 with SMTP id adf61e73a8af0-1e5e049456fmr28026644637.26.1735105481879; Tue, 24 Dec 2024 21:44:41 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-72aad90b2dcsm10580519b3a.171.2024.12.24.21.44.39 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:41 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:18 +0900 Subject: [PATCH 6/8] migration: Replace QemuSemaphore with QemuEvent MIME-Version: 1.0 Message-Id: <20241225-event-v1-6-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::62f; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62f.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org rp_pong_acks tells if it has ever received one pong. QemuEvent is better suited for this usage because it represents a boolean rather than integer and will not decrement with the wait operation. pause_event can utilize qemu_event_reset() to discard events. Signed-off-by: Akihiko Odaki --- migration/migration.h | 6 +++--- migration/migration.c | 33 +++++++++++++++------------------ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/migration/migration.h b/migration/migration.h index 0956e9274b2c..3eda64d7d241 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -337,11 +337,11 @@ struct MigrationState { */ QemuSemaphore rp_sem; /* - * We post to this when we got one PONG from dest. So far it's an + * We set this when we got one PONG from dest. So far it's an * easy way to know the main channel has successfully established * on dest QEMU. */ - QemuSemaphore rp_pong_acks; + QemuEvent rp_pong_acks; } rp_state; double mbps; @@ -377,7 +377,7 @@ struct MigrationState { QemuSemaphore wait_unplug_sem; /* Migration is paused due to pause-before-switchover */ - QemuSemaphore pause_sem; + QemuEvent pause_event; /* The semaphore is used to notify COLO thread that failover is finished */ QemuSemaphore colo_exit_sem; diff --git a/migration/migration.c b/migration/migration.c index 8c5bd0a75c85..bbce6f80e8f0 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1522,7 +1522,7 @@ static void migrate_fd_cancel(MigrationState *s) } /* If the migration is paused, kick it out of the pause */ if (old_state == MIGRATION_STATUS_PRE_SWITCHOVER) { - qemu_sem_post(&s->pause_sem); + qemu_event_set(&s->pause_event); } migrate_set_state(&s->state, old_state, MIGRATION_STATUS_CANCELLING); } while (s->state != MIGRATION_STATUS_CANCELLING); @@ -2135,7 +2135,7 @@ void qmp_migrate_continue(MigrationStatus state, Error **errp) MigrationStatus_str(s->state)); return; } - qemu_sem_post(&s->pause_sem); + qemu_event_set(&s->pause_event); } int migration_rp_wait(MigrationState *s) @@ -2343,7 +2343,7 @@ static void *source_return_path_thread(void *opaque) case MIG_RP_MSG_PONG: tmp32 = ldl_be_p(buf); trace_source_return_path_thread_pong(tmp32); - qemu_sem_post(&ms->rp_state.rp_pong_acks); + qemu_event_set(&ms->rp_state.rp_pong_acks); break; case MIG_RP_MSG_REQ_PAGES: @@ -2486,7 +2486,7 @@ static inline void migration_wait_main_channel(MigrationState *ms) { /* Wait until one PONG message received */ - qemu_sem_wait(&ms->rp_state.rp_pong_acks); + qemu_event_wait(&ms->rp_state.rp_pong_acks); } /* @@ -2686,27 +2686,24 @@ static int migration_maybe_pause(MigrationState *s, return 0; } - /* Since leaving this state is not atomic with posting the semaphore + /* + * Since leaving this state is not atomic with setting the event * it's possible that someone could have issued multiple migrate_continue - * and the semaphore is incorrectly positive at this point; - * the docs say it's undefined to reinit a semaphore that's already - * init'd, so use timedwait to eat up any existing posts. + * and the event is incorrectly set at this point so reset it. */ - while (qemu_sem_timedwait(&s->pause_sem, 1) == 0) { - /* This block intentionally left blank */ - } + qemu_event_reset(&s->pause_event); /* * If the migration is cancelled when it is in the completion phase, * the migration state is set to MIGRATION_STATUS_CANCELLING. - * So we don't need to wait a semaphore, otherwise we would always - * wait for the 'pause_sem' semaphore. + * So we don't need to wait an event, otherwise we would always + * wait for the 'pause_event' event. */ if (s->state != MIGRATION_STATUS_CANCELLING) { bql_unlock(); migrate_set_state(&s->state, *current_active_state, MIGRATION_STATUS_PRE_SWITCHOVER); - qemu_sem_wait(&s->pause_sem); + qemu_event_wait(&s->pause_event); migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER, new_state); *current_active_state = new_state; @@ -3833,10 +3830,10 @@ static void migration_instance_finalize(Object *obj) qemu_mutex_destroy(&ms->qemu_file_lock); qemu_sem_destroy(&ms->wait_unplug_sem); qemu_sem_destroy(&ms->rate_limit_sem); - qemu_sem_destroy(&ms->pause_sem); + qemu_event_destroy(&ms->pause_event); qemu_sem_destroy(&ms->postcopy_pause_sem); qemu_sem_destroy(&ms->rp_state.rp_sem); - qemu_sem_destroy(&ms->rp_state.rp_pong_acks); + qemu_event_destroy(&ms->rp_state.rp_pong_acks); qemu_sem_destroy(&ms->postcopy_qemufile_src_sem); error_free(ms->error); } @@ -3848,14 +3845,14 @@ static void migration_instance_init(Object *obj) ms->state = MIGRATION_STATUS_NONE; ms->mbps = -1; ms->pages_per_second = -1; - qemu_sem_init(&ms->pause_sem, 0); + qemu_event_init(&ms->pause_event, false); qemu_mutex_init(&ms->error_mutex); migrate_params_init(&ms->parameters); qemu_sem_init(&ms->postcopy_pause_sem, 0); qemu_sem_init(&ms->rp_state.rp_sem, 0); - qemu_sem_init(&ms->rp_state.rp_pong_acks, 0); + qemu_event_init(&ms->rp_state.rp_pong_acks, false); qemu_sem_init(&ms->rate_limit_sem, 0); qemu_sem_init(&ms->wait_unplug_sem, 0); qemu_sem_init(&ms->postcopy_qemufile_src_sem, 0); From patchwork Wed Dec 25 05:44:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920620 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E2764E7718B for ; Wed, 25 Dec 2024 05:45:48 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKCP-000792-Ir; Wed, 25 Dec 2024 00:44:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKCO-000789-Be for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:48 -0500 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKCM-0008Qx-OA for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:48 -0500 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-21631789fcdso49506365ad.1 for ; Tue, 24 Dec 2024 21:44:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105485; x=1735710285; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=9kcEUHiyxDZGRPQsNHM9e2ujEEZ3RNUAoqhQJShkCqI=; b=hnhH8vvMwvebcYwCDh/r3pgGaj7/DS1JKnvzx9DjgAXtsl9lyovaj3TfA2RsjGWCTk rD9FR7zHAJrTu90n8ZAFRkJs4ifJFE0dLWNFpHdFj0JOvt2ru7Ry6c8QEeApHq8dETUt aX6NVxDN9wY9yM8x8pVwtBYLCSaBsgPEMhp2g5VepJ87Gt3AogJluOQhqhszxkchVlkn 4i2XIhlltioVSsuS15mlp3KzMRKiCPFJeUc9lTLm7xTxSMi6YNxDiZ074lsh806E45uA YX3MFXOy8gKTr4PpqpKmqXu65VRMBmOICt5x/w+1OOxhWSBeRgKKNWuFOQV2xXr6uX6M cc4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105485; x=1735710285; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9kcEUHiyxDZGRPQsNHM9e2ujEEZ3RNUAoqhQJShkCqI=; b=fL4PhhsF7vdxmGJOOOE5eZIyDAtuxNDeuuSvmj6n2qTPgUlHaw8Ikw7jvQ6WjKSsyx b1sUc3obqlnsYUO0g2c3qROmdvr0uphquIYDhfUIORjotUZYnG+iwt/8HNOTorErPYHv tivv7Oh8Up/IqmwC/UUuGiKeNMtSYNnq3f/ocn4gMJ8WfjWJ5BH6Z7Trx//Hx3Wj5WIM YRMEXj/E1WV2PwWJHb32InN9/hwp0IAqlksYmUCNBq1cro4wT6W3GDD8QWdIWlVDD9z2 oLExvyccw/SDJ63yboVuAJ+ZCaW8nbqEQIPNac1lOQTj4qll28n55YOWMdJQJJgXXx9s QumA== X-Forwarded-Encrypted: i=1; AJvYcCXmS0YIH80+Pv+lek0HXAUK4XgxymX9Y8mO0O/6K5s0eNgcfZaVTOue+7+KP2lnbAP9ifttPOW6xodb@nongnu.org X-Gm-Message-State: AOJu0YxBJSXIOlD5BlXQhrp0kGzX+IAD48JW+0qGAC8U/gPA56f2hBN6 fhx8/s4kx27fUKWfgc0ChCaCTGUWXi6OIHXKSy4Pw2py8hifJsIwtVndM4T/Y9k= X-Gm-Gg: ASbGnctG9qZXEBGAwm5yCknZKjfWMY1vTwdFEijU6U8hcj/l+bl6IsqtmggmfIyCser S64Uk1mfE96OHPDrR/MzKxllrxnw6rgI01fP6kI1GElbCKtK0WoQbYSa0eL3unI6Q0do23Q3zk5 J0guFqSDfjIn+v0fHjGc3j7s/Uh36aCpkiib2Tj3Xkv40Lkp6XRx2Rnkc/66BPepM+9xBohSOIB DyQTALS67mh+qM/iU6VdOciN4MU7V8sHDWTuxNjpFv1CmNhwRjtxNrOJYLj X-Google-Smtp-Source: AGHT+IGwJbLuuCVHrBOvwuWs2ZWuZkhYybR5dwh9IuZpEJQkVdRqpXUw0YED3Rt/o2NdOITzXBahOA== X-Received: by 2002:a05:6a21:78aa:b0:1e4:745c:4965 with SMTP id adf61e73a8af0-1e5e1e26dc3mr27818779637.8.1735105485491; Tue, 24 Dec 2024 21:44:45 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-72afb89fedesm1197240b3a.84.2024.12.24.21.44.43 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:45 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:19 +0900 Subject: [PATCH 7/8] migration/colo: Replace QemuSemaphore with QemuEvent MIME-Version: 1.0 Message-Id: <20241225-event-v1-7-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::633; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x633.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org colo_exit_sem and colo_incoming_sem represent one-shot events so they can be converted into QemuEvent, which is more lightweight. Signed-off-by: Akihiko Odaki --- migration/migration.h | 6 +++--- migration/colo.c | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/migration/migration.h b/migration/migration.h index 3eda64d7d241..14032e347ece 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -185,7 +185,7 @@ struct MigrationIncomingState { /* The coroutine we should enter (back) after failover */ Coroutine *colo_incoming_co; - QemuSemaphore colo_incoming_sem; + QemuEvent colo_incoming_event; /* * PostcopyBlocktimeContext to keep information for postcopy @@ -379,8 +379,8 @@ struct MigrationState { /* Migration is paused due to pause-before-switchover */ QemuEvent pause_event; - /* The semaphore is used to notify COLO thread that failover is finished */ - QemuSemaphore colo_exit_sem; + /* The event is used to notify COLO thread that failover is finished */ + QemuEvent colo_exit_event; /* The event is used to notify COLO thread to do checkpoint */ QemuEvent colo_checkpoint_event; diff --git a/migration/colo.c b/migration/colo.c index 9590f281d0f1..7e29c93aa4df 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -146,7 +146,7 @@ static void secondary_vm_do_failover(void) return; } /* Notify COLO incoming thread that failover work is finished */ - qemu_sem_post(&mis->colo_incoming_sem); + qemu_event_set(&mis->colo_incoming_event); /* For Secondary VM, jump to incoming co */ if (mis->colo_incoming_co) { @@ -195,7 +195,7 @@ static void primary_vm_do_failover(void) } /* Notify COLO thread that failover work is finished */ - qemu_sem_post(&s->colo_exit_sem); + qemu_event_set(&s->colo_exit_event); } COLOMode get_colo_mode(void) @@ -617,8 +617,8 @@ out: } /* Hope this not to be too long to wait here */ - qemu_sem_wait(&s->colo_exit_sem); - qemu_sem_destroy(&s->colo_exit_sem); + qemu_event_wait(&s->colo_exit_event); + qemu_event_destroy(&s->colo_exit_event); /* * It is safe to unregister notifier after failover finished. @@ -648,7 +648,7 @@ void migrate_start_colo_process(MigrationState *s) s->colo_delay_timer = timer_new_ms(QEMU_CLOCK_HOST, colo_checkpoint_notify_timer, NULL); - qemu_sem_init(&s->colo_exit_sem, 0); + qemu_event_init(&s->colo_exit_event, false); colo_process_checkpoint(s); bql_lock(); } @@ -805,11 +805,11 @@ void colo_shutdown(void) case COLO_MODE_PRIMARY: s = migrate_get_current(); qemu_event_set(&s->colo_checkpoint_event); - qemu_sem_post(&s->colo_exit_sem); + qemu_event_set(&s->colo_exit_event); break; case COLO_MODE_SECONDARY: mis = migration_incoming_get_current(); - qemu_sem_post(&mis->colo_incoming_sem); + qemu_event_set(&mis->colo_incoming_event); break; default: break; @@ -824,7 +824,7 @@ static void *colo_process_incoming_thread(void *opaque) Error *local_err = NULL; rcu_register_thread(); - qemu_sem_init(&mis->colo_incoming_sem, 0); + qemu_event_init(&mis->colo_incoming_event, false); migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_COLO); @@ -920,8 +920,8 @@ out: } /* Hope this not to be too long to loop here */ - qemu_sem_wait(&mis->colo_incoming_sem); - qemu_sem_destroy(&mis->colo_incoming_sem); + qemu_event_wait(&mis->colo_incoming_event); + qemu_event_destroy(&mis->colo_incoming_event); rcu_unregister_thread(); return NULL; From patchwork Wed Dec 25 05:44:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 13920617 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0BDF0E77190 for ; Wed, 25 Dec 2024 05:45:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQKCT-0007A9-4j; Wed, 25 Dec 2024 00:44:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQKCR-00079d-Q3 for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:51 -0500 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQKCQ-0008Rs-57 for qemu-devel@nongnu.org; Wed, 25 Dec 2024 00:44:51 -0500 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-2162c0f6a39so68510905ad.0 for ; Tue, 24 Dec 2024 21:44:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1735105489; x=1735710289; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=BfW6loc+fFQscPvRrP8GDLS1/0I7at7KRLKoCL6/Ni0=; b=Ge2znAg5xNZe1A1sOB38lorzo1bcpbcd6MKM4amixK7OpJNudM5s/4nmfD4BMAKBCM seBAqqCvqeEreIYVV5aSVcLizGRlkHyEZ0WAwjJgSYxY89Jx+kBjUy8SNfOmgQKPdNAA XNyuIfFiZOkk9gyyFF0Mr78VLjPTBVmBfVd89MorxTPwCViWf1Mjl4XStWpoOl+21MOV qjmzJcIDc3QWOULr0t8PjwgELWVohlWuIYAxvvvlY/PZhQYStIkUsdV8WjAHpkRq55Sq jop5dgXS8J16dmT5yEBsB5NbZ2whw6zLH1g3zwMeSvDEnSFT/SUwPemxBqsY3FY+v9Bi U7wA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735105489; x=1735710289; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BfW6loc+fFQscPvRrP8GDLS1/0I7at7KRLKoCL6/Ni0=; b=mj9FeG6RsJOswKmhNA2Aph7fTcEgmOExNzoNHgwkYBWVVjWn3FFjz7d7Wd8HcBFTsm pL+1rUx0teqAycvM+kitrhE545YCRcslYTh0MuHvhUj/Ee6zp/4iwjx32s35Q+s3L/GD IGLHO+tK2XRiLYvae+yqohsD3tDxw5c0OSxEhp3mzJN1LBP1oWQ8oJsHetIa+Wnoj5X/ yxwlbibsspJAj2DiEEnI/jFSJ0ywhV/gtVqYOThdopS/wdCDupN1AsBx3CHoSbMNSKRH 2IO0l0upPcrI00rQb1562GsJzW8GhRNaBA/zhvcVcPY3StOJbJuIJgIu6avUqUbAW598 WrtQ== X-Forwarded-Encrypted: i=1; AJvYcCX3jgo3rl67f/YFHhi4MJr6pO1E7Hcrod5B2TF5/vfRRMe75a643XdJALXoNJe/416iebYPfF6RPmfH@nongnu.org X-Gm-Message-State: AOJu0YyTNNa2oRTVTJfJFEeIudW68zJsyOE+1IBYzL1FFyCf2hw/nTwc flPBoKo1FPHcuLTy53f3JDT21InUjq5cFdB27jHvoW7OYKNqOPsOugqzLUVXcMRPZt01SDMLg8c TYJo= X-Gm-Gg: ASbGncsSTDZexBTRvAQcJRIJfBvYPTHt5r7z9S8Wy9jomgey8bxoVjXYcRqy9/8xUuR Obg+p9izYyKWDArxT/TmMbYQR6va+ftwGm/8Akxqf8eMeaqdkglmE2U3pSAMPZRGOxPw8d19aGc UOpopXli5smX8e1U48G9KNgy0Sro6m39M6p9T/cxeYZRpPIf5qN8xbKwZGrHNlSkE+M77HTvFf0 y+tOxwVP3m/kG8J9SFBNPchRe9xuv7wugYyWmjd9LGTno+MmfruWZMuZVI+ X-Google-Smtp-Source: AGHT+IGj5tSFW7/HxPa8wxzeC3Nsr4XVV6a/eZZ/ifTTN8CopyXpMJrO2Jk0DBld4diyPUDhHElKdg== X-Received: by 2002:a17:902:ea10:b0:216:271d:e06c with SMTP id d9443c01a7336-219e6ca6cb3mr243789455ad.4.1735105489039; Tue, 24 Dec 2024 21:44:49 -0800 (PST) Received: from localhost ([157.82.207.107]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-219dc962cddsm98698155ad.48.2024.12.24.21.44.46 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 21:44:48 -0800 (PST) From: Akihiko Odaki Date: Wed, 25 Dec 2024 14:44:20 +0900 Subject: [PATCH 8/8] migration/postcopy: Replace QemuSemaphore with QemuEvent MIME-Version: 1.0 Message-Id: <20241225-event-v1-8-a58c8d63eb70@daynix.com> References: <20241225-event-v1-0-a58c8d63eb70@daynix.com> In-Reply-To: <20241225-event-v1-0-a58c8d63eb70@daynix.com> To: Paolo Bonzini , Stefan Weil , Peter Xu , Fabiano Rosas , Hailiang Zhang Cc: Phil Dennis-Jordan , qemu-devel@nongnu.org, devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.14-dev-fd6e3 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org thread_sync_sem is an one-shot event so it can be converted into QemuEvent, which is more lightweight. Signed-off-by: Akihiko Odaki --- migration/migration.h | 4 ++-- migration/postcopy-ram.c | 10 +++++----- migration/savevm.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/migration/migration.h b/migration/migration.h index 14032e347ece..405f69c095e4 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -97,9 +97,9 @@ struct MigrationIncomingState { void (*transport_cleanup)(void *data); /* * Used to sync thread creations. Note that we can't create threads in - * parallel with this sem. + * parallel with this event. */ - QemuSemaphore thread_sync_sem; + QemuEvent thread_sync_event; /* * Free at the start of the main state load, set as the main thread finishes * loading state. diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index a535fd2e30c9..80f780bff87c 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -90,10 +90,10 @@ void postcopy_thread_create(MigrationIncomingState *mis, QemuThread *thread, const char *name, void *(*fn)(void *), int joinable) { - qemu_sem_init(&mis->thread_sync_sem, 0); + qemu_event_init(&mis->thread_sync_event, false); qemu_thread_create(thread, name, fn, mis, joinable); - qemu_sem_wait(&mis->thread_sync_sem); - qemu_sem_destroy(&mis->thread_sync_sem); + qemu_event_wait(&mis->thread_sync_event); + qemu_event_destroy(&mis->thread_sync_event); } /* Postcopy needs to detect accesses to pages that haven't yet been copied @@ -964,7 +964,7 @@ static void *postcopy_ram_fault_thread(void *opaque) trace_postcopy_ram_fault_thread_entry(); rcu_register_thread(); mis->last_rb = NULL; /* last RAMBlock we sent part of */ - qemu_sem_post(&mis->thread_sync_sem); + qemu_event_set(&mis->thread_sync_event); struct pollfd *pfd; size_t pfd_len = 2 + mis->postcopy_remote_fds->len; @@ -1716,7 +1716,7 @@ void *postcopy_preempt_thread(void *opaque) rcu_register_thread(); - qemu_sem_post(&mis->thread_sync_sem); + qemu_event_set(&mis->thread_sync_event); /* * The preempt channel is established in asynchronous way. Wait diff --git a/migration/savevm.c b/migration/savevm.c index f4e4876f7202..03e4cb63f35b 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1987,7 +1987,7 @@ static void *postcopy_ram_listen_thread(void *opaque) migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_POSTCOPY_ACTIVE); - qemu_sem_post(&mis->thread_sync_sem); + qemu_event_set(&mis->thread_sync_event); trace_postcopy_ram_listen_thread_start(); rcu_register_thread();