Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2227797/?format=api
{ "id": 2227797, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2227797/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260424-force_rcu-v4-3-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260424-force_rcu-v4-3-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>", "date": "2026-04-24T09:27:08", "name": "[v4,3/6] rcu: Use call_rcu() in synchronize_rcu()", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "48409700d6969c321a86c29792555a792f92ce5a", "submitter": { "id": 90980, "url": "http://patchwork.ozlabs.org/api/1.1/people/90980/?format=api", "name": "Akihiko Odaki", "email": "odaki@rsg.ci.i.u-tokyo.ac.jp" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260424-force_rcu-v4-3-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp/mbox/", "series": [ { "id": 501326, "url": "http://patchwork.ozlabs.org/api/1.1/series/501326/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501326", "date": "2026-04-24T09:27:07", "name": "virtio-gpu: Force RCU when unmapping blob", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/501326/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2227797/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2227797/checks/", "tags": {}, "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"key not found in DNS\" header.d=rsg.ci.i.u-tokyo.ac.jp\n header.i=@rsg.ci.i.u-tokyo.ac.jp header.a=rsa-sha256 header.s=rs20250326\n header.b=r1WyzKCf;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g272V3tTsz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 19:29:22 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wGCqS-00010r-CE; Fri, 24 Apr 2026 05:29:08 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <odaki@rsg.ci.i.u-tokyo.ac.jp>)\n id 1wGCp3-0007MT-3h\n for qemu-devel@nongnu.org; Fri, 24 Apr 2026 05:27:41 -0400", "from www3579.sakura.ne.jp ([49.212.243.89])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <odaki@rsg.ci.i.u-tokyo.ac.jp>)\n id 1wGCoz-0007aK-NY\n for qemu-devel@nongnu.org; Fri, 24 Apr 2026 05:27:40 -0400", "from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp\n [133.11.54.205]) (authenticated bits=0)\n by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 63O9RHIf004358\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO);\n Fri, 24 Apr 2026 18:27:26 +0900 (JST)\n (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp)" ], "DKIM-Signature": "a=rsa-sha256; bh=7SYbmYKvDcRKPumrWJKsajKHA9ZFczVdAT+icArERIs=;\n c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp;\n h=From:Message-Id:To:Subject:Date;\n s=rs20250326; t=1777022846; v=1;\n b=r1WyzKCfsBIfLiK5TP5o5l70FP47lnYtx4hapwEniSOjN9Yfc2nODW+ZQPB7Pupv\n wSsfa1N9pO6HEaAw3JZr3rVpa42rCHJaqSMAO0+gtrdWHp1G8crqjLPd9Qn01RV4\n Gj+6tHF5TiYDpuLT1c4giYY67m8Ih+SJGCam37+dqNq3CV1oQ/LMj356dbtYr8pX\n UdpzdCgXgLOm2KV9T7I8CLQB3laiUwrVEy0fufUMRsmB6RE3ThjgWTHS+ykQTHTL\n RnLIyqjlSiYcwAjXglBpSIct0OtEkTS2tghvuPjQ1t//+tzmhsMPCcV1V1EjsLhh\n jBiZERECneUh8BYFAKmEjg==", "From": "Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>", "Date": "Fri, 24 Apr 2026 18:27:08 +0900", "Subject": "[PATCH v4 3/6] rcu: Use call_rcu() in synchronize_rcu()", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260424-force_rcu-v4-3-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>", "References": "<20260424-force_rcu-v4-0-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>", "In-Reply-To": "<20260424-force_rcu-v4-0-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>", "To": "qemu-devel@nongnu.org, Dmitry Osipenko <dmitry.osipenko@collabora.com>", "Cc": "Paolo Bonzini <pbonzini@redhat.com>,\n \"Michael S. Tsirkin\" <mst@redhat.com>,\n =?utf-8?q?Alex_Benn=C3=A9e?= <alex.bennee@linaro.org>,\n Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>", "X-Mailer": "b4 0.16-dev-16047", "Received-SPF": "pass client-ip=49.212.243.89;\n 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,\n DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001,\n 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 <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Previously, synchronize_rcu() was a single-threaded implementation that\nis protected with a mutex. It was used only in the RCU thread and tests,\nand real users instead use call_rcu(), which relies on the RCU thread.\n\nThe usage of synchronize_rcu() in tests did not accurately represent\nreal use cases because it caused locking with the mutex, which never\nhappened in real use cases, and it did not exercise the logic in the\nRCU thread.\n\nAdd a new implementation of synchronize_rcu() which uses call_rcu() to\nrepresent real use cases in tests. The old synchronize_rcu() is now\nrenamed to enter_qs() and only used in the RCU thread, making the mutex\nunnecessary.\n\nSigned-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>\nTested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>\n---\n util/rcu.c | 51 +++++++++++++++++++++++++++------------------------\n 1 file changed, 27 insertions(+), 24 deletions(-)", "diff": "diff --git a/util/rcu.c b/util/rcu.c\nindex acac9446ea98..3c4af9d213c8 100644\n--- a/util/rcu.c\n+++ b/util/rcu.c\n@@ -38,7 +38,7 @@\n \n /*\n * Global grace period counter. Bit 0 is always one in rcu_gp_ctr.\n- * Bits 1 and above are defined in synchronize_rcu.\n+ * Bits 1 and above are defined in enter_qs().\n */\n #define RCU_GP_LOCKED (1UL << 0)\n #define RCU_GP_CTR (1UL << 1)\n@@ -52,7 +52,6 @@ QemuEvent rcu_gp_event;\n static int in_drain_call_rcu;\n static int rcu_call_count;\n static QemuMutex rcu_registry_lock;\n-static QemuMutex rcu_sync_lock;\n \n /*\n * Check whether a quiescent state was crossed between the beginning of\n@@ -111,7 +110,7 @@ static void wait_for_readers(void)\n *\n * If this is the last iteration, this barrier also prevents\n * frees from seeping upwards, and orders the two wait phases\n- * on architectures with 32-bit longs; see synchronize_rcu().\n+ * on architectures with 32-bit longs; see enter_qs().\n */\n smp_mb_global();\n \n@@ -137,9 +136,9 @@ static void wait_for_readers(void)\n * wait too much time.\n *\n * rcu_register_thread() may add nodes to ®istry; it will not\n- * wake up synchronize_rcu, but that is okay because at least another\n+ * wake up enter_qs(), but that is okay because at least another\n * thread must exit its RCU read-side critical section before\n- * synchronize_rcu is done. The next iteration of the loop will\n+ * enter_qs() is done. The next iteration of the loop will\n * move the new thread's rcu_reader from ®istry to &qsreaders,\n * because rcu_gp_ongoing() will return false.\n *\n@@ -171,10 +170,8 @@ static void wait_for_readers(void)\n QLIST_SWAP(®istry, &qsreaders, node);\n }\n \n-void synchronize_rcu(void)\n+static void enter_qs(void)\n {\n- QEMU_LOCK_GUARD(&rcu_sync_lock);\n-\n /* Write RCU-protected pointers before reading p_rcu_reader->ctr.\n * Pairs with smp_mb_placeholder() in rcu_read_lock().\n *\n@@ -289,7 +286,7 @@ static void *call_rcu_thread(void *opaque)\n \n /*\n * Fetch rcu_call_count now, we only must process elements that were\n- * added before synchronize_rcu() starts.\n+ * added before enter_qs() starts.\n */\n for (;;) {\n qemu_event_reset(&rcu_call_ready_event);\n@@ -304,7 +301,7 @@ static void *call_rcu_thread(void *opaque)\n qemu_event_wait(&rcu_call_ready_event);\n }\n \n- synchronize_rcu();\n+ enter_qs();\n qatomic_sub(&rcu_call_count, n);\n bql_lock();\n while (n > 0) {\n@@ -337,15 +334,24 @@ void call_rcu1(struct rcu_head *node, void (*func)(struct rcu_head *node))\n }\n \n \n-struct rcu_drain {\n+typedef struct Sync {\n struct rcu_head rcu;\n- QemuEvent drain_complete_event;\n-};\n+ QemuEvent complete_event;\n+} Sync;\n \n-static void drain_rcu_callback(struct rcu_head *node)\n+static void sync_rcu_callback(Sync *sync)\n {\n- struct rcu_drain *event = (struct rcu_drain *)node;\n- qemu_event_set(&event->drain_complete_event);\n+ qemu_event_set(&sync->complete_event);\n+}\n+\n+void synchronize_rcu(void)\n+{\n+ Sync sync;\n+\n+ qemu_event_init(&sync.complete_event, false);\n+ call_rcu(&sync, sync_rcu_callback, rcu);\n+ qemu_event_wait(&sync.complete_event);\n+ qemu_event_destroy(&sync.complete_event);\n }\n \n /*\n@@ -359,11 +365,11 @@ static void drain_rcu_callback(struct rcu_head *node)\n \n void drain_call_rcu(void)\n {\n- struct rcu_drain rcu_drain;\n+ Sync sync;\n bool locked = bql_locked();\n \n- memset(&rcu_drain, 0, sizeof(struct rcu_drain));\n- qemu_event_init(&rcu_drain.drain_complete_event, false);\n+ memset(&sync, 0, sizeof(sync));\n+ qemu_event_init(&sync.complete_event, false);\n \n if (locked) {\n bql_unlock();\n@@ -383,8 +389,8 @@ void drain_call_rcu(void)\n */\n \n qatomic_inc(&in_drain_call_rcu);\n- call_rcu1(&rcu_drain.rcu, drain_rcu_callback);\n- qemu_event_wait(&rcu_drain.drain_complete_event);\n+ call_rcu(&sync, sync_rcu_callback, rcu);\n+ qemu_event_wait(&sync.complete_event);\n qatomic_dec(&in_drain_call_rcu);\n \n if (locked) {\n@@ -427,7 +433,6 @@ static void rcu_init_complete(void)\n QemuThread thread;\n \n qemu_mutex_init(&rcu_registry_lock);\n- qemu_mutex_init(&rcu_sync_lock);\n qemu_event_init(&rcu_gp_event, true);\n \n qemu_event_init(&rcu_call_ready_event, false);\n@@ -460,7 +465,6 @@ static void rcu_init_lock(void)\n return;\n }\n \n- qemu_mutex_lock(&rcu_sync_lock);\n qemu_mutex_lock(&rcu_registry_lock);\n }\n \n@@ -471,7 +475,6 @@ static void rcu_init_unlock(void)\n }\n \n qemu_mutex_unlock(&rcu_registry_lock);\n- qemu_mutex_unlock(&rcu_sync_lock);\n }\n \n static void rcu_init_child(void)\n", "prefixes": [ "v4", "3/6" ] }