From nobody Sat Feb 7 04:41:31 2026 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 1768455607602165.33608575089352; Wed, 14 Jan 2026 21:40:07 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vgG4x-0006uD-Q5; Thu, 15 Jan 2026 00:39:31 -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 1vgG4t-0006ru-Oi for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:27 -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 1vgG4n-0004fI-Kh for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:26 -0500 Received: from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp [133.11.54.205]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 60F5cwVb061416 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 15 Jan 2026 14:39:07 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=TbmQfRhW7tk1w8y2oJ/yjOqATkEcmBrVR6/713ng5E4=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1768455547; v=1; b=Xs25c2brwstefH6vbLHiQ39CrFh/AWaBN1Bv5jKzhhFfOxw/mB1fuwaMiH7luymO l3G/uKKS3wO3MdbeZNt2x8ExcXZcbQDT0t3N0QYRzLPUq8RHprHti5t0NhEiTHUc O1zyO15vDQzyjblladXDOSzWs/CW47+7KNN5xtOyCsd0ds8mxAu7ktIl8gqDNMhE wL5g9uIVjFtarzC9ja7evnw322RrfxZTB0NYSOm2RFtgrNK/8NPtnbWwMN+DHIDA eT3v5IPoGFnX2XkhDRdOwtDfnL0kEacYozX7s5n76BWBqD6dVRUWxAKroB2BBqwQ iJLTZlsD2MBwRNRBLdT23A== From: Akihiko Odaki Date: Thu, 15 Jan 2026 14:38:50 +0900 Subject: [PATCH v3 1/5] futex: Add qemu_futex_timedwait() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260115-force_rcu-v3-1-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> References: <20260115-force_rcu-v3-0-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260115-force_rcu-v3-0-1f8bfaff4815@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 (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: qemu development 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: 1768455610246158500 qemu_futex_timedwait() is equivalent to qemu_futex_wait(), except it has an absolute timeout. Signed-off-by: Akihiko Odaki Tested-by: Dmitry Osipenko --- include/qemu/futex.h | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/include/qemu/futex.h b/include/qemu/futex.h index 607613eec835..3f3b55008f61 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,22 @@ 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); + int64_t now =3D get_clock(); + DWORD duration =3D MIN((ns - now) / SCALE_MS, INFINITE); + + return ns > now && 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 Sat Feb 7 04:41:31 2026 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 1768455632542837.8793569245868; Wed, 14 Jan 2026 21:40:32 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vgG4y-0006uK-8A; Thu, 15 Jan 2026 00:39: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 1vgG4v-0006st-NQ for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:29 -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 1vgG4n-0004fL-Jd for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:28 -0500 Received: from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp [133.11.54.205]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 60F5cwVc061416 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 15 Jan 2026 14:39:07 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=j60yjpKslRyTKg/5MPqUwHkO2E1MhnIuIRKEeUYLklM=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1768455547; v=1; b=dlQPE7yLLdt0Db1SbVIQCm/ZMQnCqLrXODq76lCwQ/QwJLeiMM/xDuPLP2C8BqhC KTWyWASwvtX4DiOX/SUIcbLOOeuBST2mGrK1K9utjKtOVd5dPJRAaQV8fKJfs8DL rN46lwWmUU6X1Runrgx6KLBeMrQdy5Uga0EVO83O9fJ7Onp2DeCaq/8DAaha9mZY f1n2eZiKGq/URoe9Hl36Ov7M3qFwbg01PWqZWvlXZQJrfBEBq5uljkM6GeWBC+Lk 1PR3uF35XQKrvoX/vGgFi7faoHAZW5c31E54X1EMcZJJBr9C+xdWNmQ/QFwaTFAI 3RAjMU9CK0cCmP2gJmF6iQ== From: Akihiko Odaki Date: Thu, 15 Jan 2026 14:38:51 +0900 Subject: [PATCH v3 2/5] qemu-thread: Add qemu_event_timedwait() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260115-force_rcu-v3-2-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> References: <20260115-force_rcu-v3-0-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260115-force_rcu-v3-0-1f8bfaff4815@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 (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: qemu development 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: 1768455633911158500 qemu_event_timedwait() is equivalent to qemu_event_wait(), except it has a relative timeout. Signed-off-by: Akihiko Odaki Tested-by: Dmitry Osipenko --- 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 Sat Feb 7 04:41:31 2026 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 1768455625486812.4787918839056; Wed, 14 Jan 2026 21:40:25 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vgG4u-0006rs-Tu; Thu, 15 Jan 2026 00:39:29 -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 1vgG4r-0006rF-RQ for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:25 -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 1vgG4n-0004fF-Kk for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:25 -0500 Received: from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp [133.11.54.205]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 60F5cwVd061416 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 15 Jan 2026 14:39:07 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=DP3lnFDitt3YsA2BwiCD3h2/vaVo//qSCq0EXEOKCT0=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1768455547; v=1; b=YdE8rPyyZPXKYYgmijgQlfoog2EzOna34181onkUEqEfz+ExqHGfQ+E5fMESq5zE /6qi+3daXH7nTeGa3OZ/rSMxJ8QEmMq7E9V6J0j+LV3WzGLICSuEl3tObHiaFMHC t4z68TOnVfjhGGXXAbnFUlhqV5nGuE3qWFtK/5iufBGhWj/V9PyyCcSSIsZYRmEu /ph14wrqKvVQ0lRE3SV9hExquN4fxmwZhyGjuQnoyClRIoLoJcCrvIf3posbsPWC kew1OLvl+JKFYhKOkTFgHPBB4q/Id4vIrrUbyY/sjv66BdEY2kKIgTEWoeiJyXBe Paw6/iFrhYtovGmEZWejoA== From: Akihiko Odaki Date: Thu, 15 Jan 2026 14:38:52 +0900 Subject: [PATCH v3 3/5] 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: <20260115-force_rcu-v3-3-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> References: <20260115-force_rcu-v3-0-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260115-force_rcu-v3-0-1f8bfaff4815@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 (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: qemu development 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: 1768455627724158500 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 Tested-by: Dmitry Osipenko --- 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 Sat Feb 7 04:41:31 2026 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 176845560749972.65413695070379; Wed, 14 Jan 2026 21:40:07 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vgG4y-0006uU-O3; Thu, 15 Jan 2026 00:39: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 1vgG4t-0006rt-Ob for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:27 -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 1vgG4n-0004fA-K7 for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:26 -0500 Received: from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp [133.11.54.205]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 60F5cwVe061416 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 15 Jan 2026 14:39:07 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=mSBD9IbvDFwfq+2kxFnLIYbNxRUyli38QTiXrtCpHoQ=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1768455547; v=1; b=Ly1Fub5/z0DXaZav7YFxik7piwIW0CVb7wMgO/GoKRlP75GzNCxHZFeEXrSi6xqV BkERFY1F+gPUuWPS9hgzwbGVs1lgzc68yJ6l0mMEUs5x4mGNuRQlpPQXeKD0/Tub M6O+sPNLygD2MiVX3w/3isRqNY0qc7LEh7XIiWOr9TMpEUq6p0zwd2JqeDbGn3XC u6z1rx9D4n6cT5oAB/41AZaCaTw69WRItUJxCS0JeWWjdyYV3J2JrOdpWYe7gRSm CD+pOgddVKRM84NqAJUuo5VBAgYmfFIlV/ArD1AG4dAQvLBNYT5viIEh8aX1YvWW kDn7CHrtHXSZ5epXu/z0aA== From: Akihiko Odaki Date: Thu, 15 Jan 2026 14:38:53 +0900 Subject: [PATCH v3 4/5] 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: <20260115-force_rcu-v3-4-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> References: <20260115-force_rcu-v3-0-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260115-force_rcu-v3-0-1f8bfaff4815@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 (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: qemu development 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: 1768455610308158500 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 Tested-by: Dmitry Osipenko --- 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 Sat Feb 7 04:41:31 2026 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 1768455607773876.7953656805752; Wed, 14 Jan 2026 21:40:07 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vgG4u-0006sZ-Tx; Thu, 15 Jan 2026 00:39:29 -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 1vgG4r-0006rH-SY for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:25 -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 1vgG4n-0004fJ-Jc for qemu-devel@nongnu.org; Thu, 15 Jan 2026 00:39:24 -0500 Received: from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp [133.11.54.205]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 60F5cwVf061416 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 15 Jan 2026 14:39:07 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=NlBwYP7hYz7hXShyLqc38rtmmyvw4LTe00HInGEpDxM=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1768455547; v=1; b=NkPcQOawlW+mbhrHa26C4CJIfln48c+S4dksepWUkmTaNSG8MNdZPCz0GEtyuVTo /ZsvZFN66zr9z5ZTnl8fgjLdjn/kWsYngPw3QqvKJv1gi9E7VfgFNK4fRgZs8QSw f4PFPYxsUNs2xSDLxdZzik0Q23xhQ/yeVDRjGos8rxzvWMjudAI6Edpvc2cKlr3F uprvWLIfErBnXQeKgfUlz2VJIROV9XDJbDEtF6usujySNbaGLKgtVIvtuliVPzUL qJvTOxlWEu2m33bNBLKOa4SZWpydlnugcHeb8cdKw0V2q+ifBVWbPGQMFEqKne0n fweFe1HwvPhF9wHxebqr3A== From: Akihiko Odaki Date: Thu, 15 Jan 2026 14:38:54 +0900 Subject: [PATCH v3 5/5] 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: <20260115-force_rcu-v3-5-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> References: <20260115-force_rcu-v3-0-1f8bfaff4815@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260115-force_rcu-v3-0-1f8bfaff4815@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 (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: qemu development 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: 1768455610222158500 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 Tested-by: Dmitry Osipenko --- 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