From nobody Sun Dec 14 05:53:23 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765604590355568.7571037901884; Fri, 12 Dec 2025 21:43:10 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vUIOD-00061R-Ds; Sat, 13 Dec 2025 00:41:59 -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 1vUIO8-00060M-GE for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:53 -0500 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vUIO5-0002lv-8h for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:52 -0500 Received: from [10.200.7.128] (fs96f9c361.tkyc007.ap.nuro.jp [150.249.195.97]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5BD5fMh5021206 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 13 Dec 2025 14:41:36 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=BGY2ydZ9DW/wM8vz+C2bRvZNL/uWtNVIK4HlTDmTvOw=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1765604496; v=1; b=NeqxvlgnGUdFoOdgurjfIDWexbhXikUvqNzpPt7IEK6aPPPdXDutziadl/WB8/br i9rzOfYV29lreQCZCNOfRyXujko2MLgdw5ITdTIo+V4Lp/GCJkwg2IwrrvV7YaPa sZ94ZCH7DvNnrrBkp1+QV4gj92q8dlxXI7+/dkXORyQ+kQ1Hv9s4ChhhqElLIm5z Ng0HRl3BqL5ScWM898gjEfkIVMi6wAYs+dvODg54wE690i4S1BwMKE/j3zzwPAN0 FcZnz9bZP0pzJagmhp4O6vwzUzjh2m5857hhfQixcdlaDmvqVw0upKY+okn225bq Njz9JU+05kcfBm9TPzsT0Q== From: Akihiko Odaki Date: Sat, 13 Dec 2025 14:41:20 +0900 Subject: [PATCH v2 1/6] timer: Rename init_clocks() to qemu_clock_init() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251213-force_rcu-v2-1-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> References: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org, Dmitry Osipenko Cc: Paolo Bonzini , "Michael S. Tsirkin" , =?utf-8?q?Alex_Benn=C3=A9e?= , Akihiko Odaki X-Mailer: b4 0.15-dev-179e8 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=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1765604592591158500 tests/qtest/stm32l4x5_usart-test.c will include qemu/timer.h in a suceeding change, but it causes a conflict of init_clocks() definitions. Since other functions that operate on clocks are prefixed with qemu_clock_, follow the convention by renaming init_clocks() to qemu_clock_init() and avoid the name conflict in the suceeding change. Signed-off-by: Akihiko Odaki --- include/qemu/timer.h | 4 ++-- tests/unit/test-aio-multithread.c | 2 +- util/main-loop.c | 2 +- util/qemu-timer.c | 7 ++++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 406d74112030..9dfde0660d0e 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -786,11 +786,11 @@ static inline int64_t qemu_soonest_timeout(int64_t ti= meout1, int64_t timeout2) } =20 /** - * initclocks: + * qemu_clock_init: * * Initialise the clock & timer infrastructure */ -void init_clocks(QEMUTimerListNotifyCB *notify_cb); +void qemu_clock_init(QEMUTimerListNotifyCB *notify_cb); =20 static inline int64_t get_max_clock_jump(void) { diff --git a/tests/unit/test-aio-multithread.c b/tests/unit/test-aio-multit= hread.c index 0ead6bf34ad1..33720b3ffff0 100644 --- a/tests/unit/test-aio-multithread.c +++ b/tests/unit/test-aio-multithread.c @@ -443,7 +443,7 @@ static void test_multi_mutex_10(void) =20 int main(int argc, char **argv) { - init_clocks(NULL); + qemu_clock_init(NULL); =20 g_test_init(&argc, &argv, NULL); g_test_add_func("/aio/multi/lifecycle", test_lifecycle); diff --git a/util/main-loop.c b/util/main-loop.c index b8ddda8f5eec..718b87e05c74 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -162,7 +162,7 @@ int qemu_init_main_loop(Error **errp) int ret; GSource *src; =20 - init_clocks(qemu_timer_notify_cb); + qemu_clock_init(qemu_timer_notify_cb); =20 ret =3D qemu_signal_init(errp); if (ret) { diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 56f11b6a641f..c96856d70123 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -121,7 +121,8 @@ void timerlist_free(QEMUTimerList *timer_list) g_free(timer_list); } =20 -static void qemu_clock_init(QEMUClockType type, QEMUTimerListNotifyCB *not= ify_cb) +static void qemu_clock_init_one(QEMUClockType type, + QEMUTimerListNotifyCB *notify_cb) { QEMUClock *clock =3D qemu_clock_ptr(type); =20 @@ -637,11 +638,11 @@ static void qemu_virtual_clock_set_ns(int64_t time) return cpus_set_virtual_clock(time); } =20 -void init_clocks(QEMUTimerListNotifyCB *notify_cb) +void qemu_clock_init(QEMUTimerListNotifyCB *notify_cb) { QEMUClockType type; for (type =3D 0; type < QEMU_CLOCK_MAX; type++) { - qemu_clock_init(type, notify_cb); + qemu_clock_init_one(type, notify_cb); } =20 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK --=20 2.52.0 From nobody Sun Dec 14 05:53:23 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765604586254744.3475140517421; Fri, 12 Dec 2025 21:43:06 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vUIOG-000626-1w; Sat, 13 Dec 2025 00:42:00 -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 1vUIO8-00060L-EH for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:53 -0500 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vUIO5-0002ls-8c for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:52 -0500 Received: from [10.200.7.128] (fs96f9c361.tkyc007.ap.nuro.jp [150.249.195.97]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5BD5fMh6021206 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 13 Dec 2025 14:41:36 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=L0B9jhJeb3zKvYSXK8vray0X2b7UJO76FxjV/uZ6Yhg=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1765604496; v=1; b=ogIPCXzmnzswqlljplj+XGP90M8yT1krbtjc+kJGbBvl50owpp0rfRXHLNSbosMS pJzePFS4zpnWi18PTyp2VYlHANBxqFvxvgoKLQ7+e/EWL/H/wSEaF6dfsauisfUJ S0U4mvhGMPR1aHlV6mkefvdi/u+lErDqAZgR/1WrKsB436bgQEAqhxXcV0SboYYY F9OwTn0nmWOHgb4tTmigd8MtF5HhcUQXNjf2mUWFvbGche1qBdFkrqbxI1aqcWqh dyr9bnN1OIRteSUlz4WGBFf/S9t2FKCPlcshoK6Fsiyg9JHKFvkMgqi7PRMk9YQj Y0Bq5deikVDMlB1E/gShkw== From: Akihiko Odaki Date: Sat, 13 Dec 2025 14:41:21 +0900 Subject: [PATCH v2 2/6] futex: Add qemu_futex_timedwait() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251213-force_rcu-v2-2-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> References: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org, Dmitry Osipenko Cc: Paolo Bonzini , "Michael S. Tsirkin" , =?utf-8?q?Alex_Benn=C3=A9e?= , Akihiko Odaki X-Mailer: b4 0.15-dev-179e8 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=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1765604586735158500 qemu_futex_timedwait() is equivalent to qemu_futex_wait(), except it has an absolute timeout. Signed-off-by: Akihiko Odaki --- include/qemu/futex.h | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/include/qemu/futex.h b/include/qemu/futex.h index 607613eec835..5b48f79bf329 100644 --- a/include/qemu/futex.h +++ b/include/qemu/futex.h @@ -24,13 +24,19 @@ #ifndef QEMU_FUTEX_H #define QEMU_FUTEX_H =20 +#include "qemu/timer.h" #define HAVE_FUTEX =20 #ifdef CONFIG_LINUX #include #include +#include =20 +#ifdef __NR_futex_time64 +#define qemu_futex(...) syscall(__NR_futex_time64, __VA_ARGS_= _) +#else #define qemu_futex(...) syscall(__NR_futex, __VA_ARGS__) +#endif =20 static inline void qemu_futex_wake_all(void *f) { @@ -42,18 +48,28 @@ static inline void qemu_futex_wake_single(void *f) qemu_futex(f, FUTEX_WAKE, 1, NULL, NULL, 0); } =20 -static inline void qemu_futex_wait(void *f, unsigned val) +static inline bool qemu_futex_timedwait(void *f, unsigned val, int64_t ns) { - while (qemu_futex(f, FUTEX_WAIT, (int) val, NULL, NULL, 0)) { + struct __kernel_timespec ts; + uint32_t bitset =3D FUTEX_BITSET_MATCH_ANY; + + ts.tv_sec =3D ns / NANOSECONDS_PER_SECOND; + ts.tv_nsec =3D ns % NANOSECONDS_PER_SECOND; + + while (qemu_futex(f, FUTEX_WAIT_BITSET, (int) val, &ts, NULL, bitset))= { switch (errno) { case EWOULDBLOCK: - return; + return true; case EINTR: break; /* get out of switch and retry */ + case ETIMEDOUT: + return false; default: abort(); } } + + return true; } #elif defined(CONFIG_WIN32) #include @@ -68,12 +84,20 @@ static inline void qemu_futex_wake_single(void *f) WakeByAddressSingle(f); } =20 -static inline void qemu_futex_wait(void *f, unsigned val) +static inline bool qemu_futex_timedwait(void *f, unsigned val, int64_t ns) { - WaitOnAddress(f, &val, sizeof(val), INFINITE); + DWORD duration =3D MIN((ns - get_clock()) / SCALE_MS, INFINITE); + return WaitOnAddress(f, &val, sizeof(val), duration); } #else #undef HAVE_FUTEX #endif =20 +#ifdef HAVE_FUTEX +static inline void qemu_futex_wait(void *f, unsigned val) +{ + qemu_futex_timedwait(f, val, INT64_MAX); +} +#endif + #endif /* QEMU_FUTEX_H */ --=20 2.52.0 From nobody Sun Dec 14 05:53:23 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765604565272590.6189304340942; Fri, 12 Dec 2025 21:42:45 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vUIOJ-000644-Tu; Sat, 13 Dec 2025 00:42:03 -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 1vUIO7-000603-5r for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:51 -0500 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vUIO4-0002lp-9d for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:50 -0500 Received: from [10.200.7.128] (fs96f9c361.tkyc007.ap.nuro.jp [150.249.195.97]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5BD5fMh7021206 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 13 Dec 2025 14:41:36 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=KLJ9U5F9WNRfAMT6SfglS3+AJUlDHzM1cK+vRuTmtEo=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1765604496; v=1; b=iUaz7fohT7m4PyJ1zdboG+atcbdHcvD6UYTJ3ZU/xNduXc8ZhBAFG9HtdgmQKJWz oVULXcdttDhfpzhjrZaEbOotclaHGtPDt+M4JnkXdTcHX2LJo1hCJLqmVT8ZAt6y ZuzibzLV3IFZ82UBURbS9ws4hduixvD3kd8oZifgXu6Cy7NY6TqyssYzXJFg2oOx nP6ZSyvGaJYT3aEm4aL7a8+L8w6idGSJob7AzPvdeXOvgI1cz2wUDEYLUjfihUxs hp87djwZxoXH69ntQjsiyOp0mrDQRzNhB3qi0AWHJ62b8xmXpvXlrKsZGrdnlcVH F6TPHpHcjpWG/r3utclXow== From: Akihiko Odaki Date: Sat, 13 Dec 2025 14:41:22 +0900 Subject: [PATCH v2 3/6] qemu-thread: Add qemu_event_timedwait() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251213-force_rcu-v2-3-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> References: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org, Dmitry Osipenko Cc: Paolo Bonzini , "Michael S. Tsirkin" , =?utf-8?q?Alex_Benn=C3=A9e?= , Akihiko Odaki X-Mailer: b4 0.15-dev-179e8 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=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1765604567252158500 qemu_event_timedwait() is equivalent to qemu_event_wait(), except it has a relative timeout. Signed-off-by: Akihiko Odaki --- include/qemu/thread-posix.h | 11 +++++++++++ include/qemu/thread.h | 8 +++++++- util/event.c | 28 +++++++++++++++++++++++----- util/qemu-thread-posix.c | 11 +---------- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h index 758808b705e4..11193b1580f8 100644 --- a/include/qemu/thread-posix.h +++ b/include/qemu/thread-posix.h @@ -36,4 +36,15 @@ struct QemuThread { pthread_t thread; }; =20 +static inline clockid_t qemu_timedwait_clockid(void) +{ +#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK + return CLOCK_MONOTONIC; +#else + return CLOCK_REALTIME; +#endif +} + +void compute_abs_deadline(struct timespec *ts, int ms); + #endif diff --git a/include/qemu/thread.h b/include/qemu/thread.h index f0302ed01fdb..1b08b0bcb66a 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -201,7 +201,13 @@ void qemu_sem_destroy(QemuSemaphore *sem); void qemu_event_init(QemuEvent *ev, bool init); void qemu_event_set(QemuEvent *ev); void qemu_event_reset(QemuEvent *ev); -void qemu_event_wait(QemuEvent *ev); +void qemu_event_timedwait(QemuEvent *ev, int ms); + +static inline void qemu_event_wait(QemuEvent *ev) +{ + qemu_event_timedwait(ev, INT_MAX); +} + void qemu_event_destroy(QemuEvent *ev); =20 void qemu_thread_create(QemuThread *thread, const char *name, diff --git a/util/event.c b/util/event.c index 5a8141cd0e46..cb26a0bfb952 100644 --- a/util/event.c +++ b/util/event.c @@ -33,7 +33,15 @@ void qemu_event_init(QemuEvent *ev, bool init) { #ifndef HAVE_FUTEX pthread_mutex_init(&ev->lock, NULL); +#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK + pthread_condattr_t attr; + pthread_condattr_init(&attr); + pthread_condattr_setclock(&attr, qemu_timedwait_clockid()); + pthread_cond_init(&ev->cond, &attr); + pthread_condattr_destroy(&attr); +#else pthread_cond_init(&ev->cond, NULL); +#endif #endif =20 ev->value =3D (init ? EV_SET : EV_FREE); @@ -121,15 +129,17 @@ void qemu_event_reset(QemuEvent *ev) #endif } =20 -void qemu_event_wait(QemuEvent *ev) +void qemu_event_timedwait(QemuEvent *ev, int ms) { assert(ev->initialized); =20 #ifdef HAVE_FUTEX + int64_t deadline =3D get_clock() + (int64_t)ms * SCALE_MS; + 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 + * qemu_event_timedwait 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(). */ unsigned value =3D qatomic_load_acquire(&ev->value); @@ -159,12 +169,20 @@ void qemu_event_wait(QemuEvent *ev) * 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); + if (!qemu_futex_timedwait(ev, EV_BUSY, deadline)) { + break; + } } #else + struct timespec ts; + + compute_abs_deadline(&ts, ms); + pthread_mutex_lock(&ev->lock); while (qatomic_read(&ev->value) !=3D EV_SET) { - pthread_cond_wait(&ev->cond, &ev->lock); + if (pthread_cond_timedwait(&ev->cond, &ev->lock, &ts)) { + break; + } } pthread_mutex_unlock(&ev->lock); #endif diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index ba725444ba63..f649bfa00015 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -44,16 +44,7 @@ static void error_exit(int err, const char *msg) abort(); } =20 -static inline clockid_t qemu_timedwait_clockid(void) -{ -#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK - return CLOCK_MONOTONIC; -#else - return CLOCK_REALTIME; -#endif -} - -static void compute_abs_deadline(struct timespec *ts, int ms) +void compute_abs_deadline(struct timespec *ts, int ms) { clock_gettime(qemu_timedwait_clockid(), ts); ts->tv_nsec +=3D (ms % 1000) * 1000000; --=20 2.52.0 From nobody Sun Dec 14 05:53:23 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765604566870519.1979203607807; Fri, 12 Dec 2025 21:42:46 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vUIOG-00062L-8M; Sat, 13 Dec 2025 00:42:00 -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 1vUIO9-00060z-PG for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:54 -0500 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vUIO5-0002lu-T7 for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:53 -0500 Received: from [10.200.7.128] (fs96f9c361.tkyc007.ap.nuro.jp [150.249.195.97]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5BD5fMh8021206 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 13 Dec 2025 14:41:36 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=ZLXa1OkhAl18Vfmyy2upXDtKbUIi9Uc/X1KonrMu2bQ=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1765604496; v=1; b=qU6zrTB4nDVLezVFhzQ8Ir0gjUJaVGu+s/gptKvZw8QDqKxcoA0pgQILnZ5na2sj E8bRuZaDmgKb4y8/z7mpwiPu6U5ZS1KZ3Q8I/d3c/vw96PZgs7iKEPn6AU3T9Q7w Ew4OEA/mC4pBYO+FSXm0/EtL0bOWP9LXg0i/dHyPKlLdb18uLUl/IohPVdu1I0Ig Tnw5VcjWC8nfH+0neqjxhGlpTPSbEKVP54lps3vKw9OXqm6XX9uqcfYUixyScQm8 BADp5Y4TQuFTteOOnRCFGUux9X96pjKaHG004CEmN/VnwmUYbeKV60WmuJZb6aSX Khh/pQS7spHXEloN3ZW/6g== From: Akihiko Odaki Date: Sat, 13 Dec 2025 14:41:23 +0900 Subject: [PATCH v2 4/6] rcu: Use call_rcu() in synchronize_rcu() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251213-force_rcu-v2-4-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> References: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org, Dmitry Osipenko Cc: Paolo Bonzini , "Michael S. Tsirkin" , =?utf-8?q?Alex_Benn=C3=A9e?= , Akihiko Odaki X-Mailer: b4 0.15-dev-179e8 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=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1765604570512158500 Previously, synchronize_rcu() was a single-threaded implementation that is protected with a mutex. It was used only in the RCU thread and tests, and real users instead use call_rcu(), which relies on the RCU thread. The usage of synchronize_rcu() in tests did not accurately represent real use cases because it caused locking with the mutex, which never happened in real use cases, and it did not exercise the logic in the RCU thread. Add a new implementation of synchronize_rcu() which uses call_rcu() to represent real use cases in tests. The old synchronize_rcu() is now renamed to enter_qs() and only used in the RCU thread, making the mutex unnecessary. Signed-off-by: Akihiko Odaki --- util/rcu.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/util/rcu.c b/util/rcu.c index acac9446ea98..3c4af9d213c8 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -38,7 +38,7 @@ =20 /* * Global grace period counter. Bit 0 is always one in rcu_gp_ctr. - * Bits 1 and above are defined in synchronize_rcu. + * Bits 1 and above are defined in enter_qs(). */ #define RCU_GP_LOCKED (1UL << 0) #define RCU_GP_CTR (1UL << 1) @@ -52,7 +52,6 @@ QemuEvent rcu_gp_event; static int in_drain_call_rcu; static int rcu_call_count; static QemuMutex rcu_registry_lock; -static QemuMutex rcu_sync_lock; =20 /* * Check whether a quiescent state was crossed between the beginning of @@ -111,7 +110,7 @@ static void wait_for_readers(void) * * If this is the last iteration, this barrier also prevents * frees from seeping upwards, and orders the two wait phases - * on architectures with 32-bit longs; see synchronize_rcu(). + * on architectures with 32-bit longs; see enter_qs(). */ smp_mb_global(); =20 @@ -137,9 +136,9 @@ static void wait_for_readers(void) * wait too much time. * * rcu_register_thread() may add nodes to ®istry; it will not - * wake up synchronize_rcu, but that is okay because at least anot= her + * wake up enter_qs(), but that is okay because at least another * thread must exit its RCU read-side critical section before - * synchronize_rcu is done. The next iteration of the loop will + * enter_qs() is done. The next iteration of the loop will * move the new thread's rcu_reader from ®istry to &qsreaders, * because rcu_gp_ongoing() will return false. * @@ -171,10 +170,8 @@ static void wait_for_readers(void) QLIST_SWAP(®istry, &qsreaders, node); } =20 -void synchronize_rcu(void) +static void enter_qs(void) { - QEMU_LOCK_GUARD(&rcu_sync_lock); - /* Write RCU-protected pointers before reading p_rcu_reader->ctr. * Pairs with smp_mb_placeholder() in rcu_read_lock(). * @@ -289,7 +286,7 @@ static void *call_rcu_thread(void *opaque) =20 /* * Fetch rcu_call_count now, we only must process elements that we= re - * added before synchronize_rcu() starts. + * added before enter_qs() starts. */ for (;;) { qemu_event_reset(&rcu_call_ready_event); @@ -304,7 +301,7 @@ static void *call_rcu_thread(void *opaque) qemu_event_wait(&rcu_call_ready_event); } =20 - synchronize_rcu(); + enter_qs(); qatomic_sub(&rcu_call_count, n); bql_lock(); while (n > 0) { @@ -337,15 +334,24 @@ void call_rcu1(struct rcu_head *node, void (*func)(st= ruct rcu_head *node)) } =20 =20 -struct rcu_drain { +typedef struct Sync { struct rcu_head rcu; - QemuEvent drain_complete_event; -}; + QemuEvent complete_event; +} Sync; =20 -static void drain_rcu_callback(struct rcu_head *node) +static void sync_rcu_callback(Sync *sync) { - struct rcu_drain *event =3D (struct rcu_drain *)node; - qemu_event_set(&event->drain_complete_event); + qemu_event_set(&sync->complete_event); +} + +void synchronize_rcu(void) +{ + Sync sync; + + qemu_event_init(&sync.complete_event, false); + call_rcu(&sync, sync_rcu_callback, rcu); + qemu_event_wait(&sync.complete_event); + qemu_event_destroy(&sync.complete_event); } =20 /* @@ -359,11 +365,11 @@ static void drain_rcu_callback(struct rcu_head *node) =20 void drain_call_rcu(void) { - struct rcu_drain rcu_drain; + Sync sync; bool locked =3D bql_locked(); =20 - memset(&rcu_drain, 0, sizeof(struct rcu_drain)); - qemu_event_init(&rcu_drain.drain_complete_event, false); + memset(&sync, 0, sizeof(sync)); + qemu_event_init(&sync.complete_event, false); =20 if (locked) { bql_unlock(); @@ -383,8 +389,8 @@ void drain_call_rcu(void) */ =20 qatomic_inc(&in_drain_call_rcu); - call_rcu1(&rcu_drain.rcu, drain_rcu_callback); - qemu_event_wait(&rcu_drain.drain_complete_event); + call_rcu(&sync, sync_rcu_callback, rcu); + qemu_event_wait(&sync.complete_event); qatomic_dec(&in_drain_call_rcu); =20 if (locked) { @@ -427,7 +433,6 @@ static void rcu_init_complete(void) QemuThread thread; =20 qemu_mutex_init(&rcu_registry_lock); - qemu_mutex_init(&rcu_sync_lock); qemu_event_init(&rcu_gp_event, true); =20 qemu_event_init(&rcu_call_ready_event, false); @@ -460,7 +465,6 @@ static void rcu_init_lock(void) return; } =20 - qemu_mutex_lock(&rcu_sync_lock); qemu_mutex_lock(&rcu_registry_lock); } =20 @@ -471,7 +475,6 @@ static void rcu_init_unlock(void) } =20 qemu_mutex_unlock(&rcu_registry_lock); - qemu_mutex_unlock(&rcu_sync_lock); } =20 static void rcu_init_child(void) --=20 2.52.0 From nobody Sun Dec 14 05:53:23 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765604592195133.54812340612568; Fri, 12 Dec 2025 21:43:12 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vUIOA-00061C-Lv; Sat, 13 Dec 2025 00:41:55 -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 1vUIO7-000604-6L for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:51 -0500 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vUIO4-0002lt-9K for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:50 -0500 Received: from [10.200.7.128] (fs96f9c361.tkyc007.ap.nuro.jp [150.249.195.97]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5BD5fMh9021206 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 13 Dec 2025 14:41:36 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=xW6nxdP1WnT6uah7iD4+3rpmvC/VKj++w+/6JQL3bzo=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1765604496; v=1; b=DPCjaOYbJNdA884t7C2pVUZuDdn2oMm5X3F59j1fCQIi8NDHtK5hWPgFnzwZzW2A 3lKfLtoclGG7mDcFygDB+ajCyAWB20tGLJVJD6LiNTTTQNmACsWVaDmVbCFWSgP+ y5H11yDAvevV1PHVx9XbvYGB9VCAyCJGJH11ZKCgywn//VZSxu2/V85ss0q/rNEG y+YDFuYFws+QirK9tuQKaVSpk+o0JX/UwVZlNmxwkKzXTg4NEmK9Fb4jcYk/FEx8 mNIpWcyLLJO2SjWfbjdTEMVcohWlN7FUV59qlIJvbfT0QPM+FzXyw8SoM9Bg0gND 4GrqpfElXLV/TV0zJJFRug== From: Akihiko Odaki Date: Sat, 13 Dec 2025 14:41:24 +0900 Subject: [PATCH v2 5/6] rcu: Wake the RCU thread when draining MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251213-force_rcu-v2-5-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> References: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org, Dmitry Osipenko Cc: Paolo Bonzini , "Michael S. Tsirkin" , =?utf-8?q?Alex_Benn=C3=A9e?= , Akihiko Odaki X-Mailer: b4 0.15-dev-179e8 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=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1765604592616158500 drain_call_rcu() triggers the force quiescent state, but it can be delayed if the RCU thread is sleeping. Ensure the force quiescent state is immediately triggered by waking the RCU thread up. The logic to trigger the force quiescent state is decoupled as force_rcu() so that it can be used independently. Signed-off-by: Akihiko Odaki --- include/qemu/rcu.h | 1 + util/rcu.c | 51 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 020dbe4d8b77..d6aa4e5854d3 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -118,6 +118,7 @@ static inline void rcu_read_unlock(void) } } =20 +void force_rcu(void); void synchronize_rcu(void); =20 /* diff --git a/util/rcu.c b/util/rcu.c index 3c4af9d213c8..2f58f3627f74 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -45,12 +45,14 @@ =20 =20 #define RCU_CALL_MIN_SIZE 30 +#define RCU_CALL_STATE_FORCED ((uint32_t)1 << 31) +#define RCU_CALL_STATE_COUNT (~RCU_CALL_STATE_FORCED) =20 unsigned long rcu_gp_ctr =3D RCU_GP_LOCKED; =20 QemuEvent rcu_gp_event; -static int in_drain_call_rcu; -static int rcu_call_count; +static QemuEvent rcu_call_force_event; +static uint32_t rcu_call_state; static QemuMutex rcu_registry_lock; =20 /* @@ -74,28 +76,35 @@ QEMU_DEFINE_CO_TLS(struct rcu_reader_data, rcu_reader) typedef QLIST_HEAD(, rcu_reader_data) ThreadList; static ThreadList registry =3D QLIST_HEAD_INITIALIZER(registry); =20 +void force_rcu(void) +{ + qatomic_or(&rcu_call_state, RCU_CALL_STATE_FORCED); + qemu_event_set(&rcu_call_force_event); +} + /* Wait for previous parity/grace period to be empty of readers. */ -static void wait_for_readers(void) +static void wait_for_readers(bool force) { ThreadList qsreaders =3D QLIST_HEAD_INITIALIZER(qsreaders); struct rcu_reader_data *index, *tmp; - int sleeps =3D 0; + int sleeps =3D force ? 0 : 5; bool forced =3D false; =20 + qemu_event_reset(&rcu_call_force_event); + for (;;) { /* * Force the grace period to end and wait for it if any of the * following heuristical conditions are satisfied: * - A decent number of callbacks piled up. + * - force_rcu() was called. * - It timed out. - * - It is in a drain_call_rcu() call. * * Otherwise, periodically poll the grace period, hoping it ends * promptly. */ if (!forced && - (qatomic_read(&rcu_call_count) >=3D RCU_CALL_MIN_SIZE || - sleeps >=3D 5 || qatomic_read(&in_drain_call_rcu))) { + (qatomic_read(&rcu_call_state) >=3D RCU_CALL_MIN_SIZE || !slee= ps)) { forced =3D true; =20 QLIST_FOREACH(index, ®istry, node) { @@ -159,8 +168,8 @@ static void wait_for_readers(void) */ qemu_event_reset(&rcu_gp_event); } else { - g_usleep(10000); - sleeps++; + qemu_event_timedwait(&rcu_call_force_event, 10); + sleeps--; } =20 qemu_mutex_lock(&rcu_registry_lock); @@ -170,7 +179,7 @@ static void wait_for_readers(void) QLIST_SWAP(®istry, &qsreaders, node); } =20 -static void enter_qs(void) +static void enter_qs(bool force) { /* Write RCU-protected pointers before reading p_rcu_reader->ctr. * Pairs with smp_mb_placeholder() in rcu_read_lock(). @@ -189,14 +198,14 @@ static void enter_qs(void) * Switch parity: 0 -> 1, 1 -> 0. */ qatomic_set(&rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR); - wait_for_readers(); + wait_for_readers(force); qatomic_set(&rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR); } else { /* Increment current grace period. */ qatomic_set(&rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR); } =20 - wait_for_readers(); + wait_for_readers(force); } } =20 @@ -282,15 +291,17 @@ static void *call_rcu_thread(void *opaque) rcu_register_thread(); =20 for (;;) { - int n; + uint32_t state; + uint32_t n; =20 /* - * Fetch rcu_call_count now, we only must process elements that we= re + * Fetch rcu_call_state now, we only must process elements that we= re * added before enter_qs() starts. */ for (;;) { qemu_event_reset(&rcu_call_ready_event); - n =3D qatomic_read(&rcu_call_count); + state =3D qatomic_fetch_and(&rcu_call_state, RCU_CALL_STATE_CO= UNT); + n =3D state & RCU_CALL_STATE_COUNT; if (n) { break; } @@ -301,8 +312,8 @@ static void *call_rcu_thread(void *opaque) qemu_event_wait(&rcu_call_ready_event); } =20 - enter_qs(); - qatomic_sub(&rcu_call_count, n); + enter_qs(state & RCU_CALL_STATE_FORCED); + qatomic_sub(&rcu_call_state, n); bql_lock(); while (n > 0) { node =3D try_dequeue(); @@ -329,7 +340,7 @@ void call_rcu1(struct rcu_head *node, void (*func)(stru= ct rcu_head *node)) { node->func =3D func; enqueue(node); - qatomic_inc(&rcu_call_count); + qatomic_inc(&rcu_call_state); qemu_event_set(&rcu_call_ready_event); } =20 @@ -388,10 +399,9 @@ void drain_call_rcu(void) * assumed. */ =20 - qatomic_inc(&in_drain_call_rcu); call_rcu(&sync, sync_rcu_callback, rcu); + force_rcu(); qemu_event_wait(&sync.complete_event); - qatomic_dec(&in_drain_call_rcu); =20 if (locked) { bql_lock(); @@ -435,6 +445,7 @@ static void rcu_init_complete(void) qemu_mutex_init(&rcu_registry_lock); qemu_event_init(&rcu_gp_event, true); =20 + qemu_event_init(&rcu_call_force_event, false); qemu_event_init(&rcu_call_ready_event, false); =20 /* The caller is assumed to have BQL, so the call_rcu thread --=20 2.52.0 From nobody Sun Dec 14 05:53:23 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1765604603884381.71952566389814; Fri, 12 Dec 2025 21:43:23 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vUIOG-00062M-85; Sat, 13 Dec 2025 00:42:00 -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 1vUIO8-00060K-Av for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:53 -0500 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vUIO4-0002lr-EQ for qemu-devel@nongnu.org; Sat, 13 Dec 2025 00:41:51 -0500 Received: from [10.200.7.128] (fs96f9c361.tkyc007.ap.nuro.jp [150.249.195.97]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5BD5fMhA021206 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 13 Dec 2025 14:41:36 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=pyr4HKzkIZwNCn70z1uAktYDmL7mwGwvln5Y9IS/mzk=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1765604496; v=1; b=Yaux9g+8I7d8xkXaDCi2kXFWBBTevRYIAytbAugvA+Ev/SGHSgBD0jzu5yfhclGP wC6Xs8XnmYXy5p1DjDtM1Y4jvRU0nR5J5zPSB8EXYunKdjKkeFZ/W99Eq6v3FkbI jcAPo08T9nbzAn8Q+DtsRhwkJPt//B6Zlvpk6DCCS0pmD5js5tT2nKTAlk6IuUjH NnLT98roFOVSXj1/Tp8Lp+vbHzFmeN0rzyrkeG9INJMhiM/VX72nLqQ/ppt3kKk3 mowl6GqMe3cLjqSf35OnIpqmHcPyiwK/vPHfIQzbto2gzUAboIU8bnJVV6/gNgto V79wkFSN4OlJkJOd7LO6pg== From: Akihiko Odaki Date: Sat, 13 Dec 2025 14:41:25 +0900 Subject: [PATCH v2 6/6] virtio-gpu: Force RCU when unmapping blob MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251213-force_rcu-v2-6-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> References: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20251213-force_rcu-v2-0-1de1ca84c6d6@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org, Dmitry Osipenko Cc: Paolo Bonzini , "Michael S. Tsirkin" , =?utf-8?q?Alex_Benn=C3=A9e?= , Akihiko Odaki X-Mailer: b4 0.15-dev-179e8 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=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1765604604603158500 Unmapping a blob changes the memory map, which is protected with RCU. RCU is designed to minimize the read-side overhead at the cost of reclamation delay. While this design usually makes sense, it is problematic when unmapping a blob because the operation blocks all virtio-gpu commands and causes perceivable disruption. Minimize such the disruption with force_rcu(), which minimizes the reclamation delay at the cost of a read-side overhead. Signed-off-by: Akihiko Odaki --- hw/display/virtio-gpu-virgl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index 07f6355ad62e..71cde671c193 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -187,6 +187,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g, memory_region_set_enabled(mr, false); memory_region_del_subregion(&b->hostmem, mr); object_unparent(OBJECT(mr)); + force_rcu(); } =20 return 0; --=20 2.52.0