[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 21/21] plugins: fix race condition with scoreboards
From: |
Alex Bennée |
Subject: |
[PATCH v2 21/21] plugins: fix race condition with scoreboards |
Date: |
Tue, 13 Aug 2024 21:23:29 +0100 |
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
A deadlock can be created if a new vcpu (a) triggers a scoreboard
reallocation, and another vcpu (b) wants to create a new scoreboard at
the same time.
In this case, (a) holds the plugin lock, and starts an exclusive
section, waiting for (b). But at the same time, (b) is waiting for
plugin lock.
The solution is to drop the lock before entering the exclusive section.
This bug can be easily reproduced by creating a callback for any tb
exec, that allocates a new scoreboard. In this case, as soon as we reach
more than 16 vcpus, the deadlock occurs.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2344
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Message-Id: <20240812220748.95167-2-pierrick.bouvier@linaro.org>
[AJB: tweak var position to meet coding style]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
plugins/core.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/plugins/core.c b/plugins/core.c
index 12c67b4b4e..2897453cac 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -214,30 +214,49 @@ CPUPluginState *qemu_plugin_create_vcpu_state(void)
static void plugin_grow_scoreboards__locked(CPUState *cpu)
{
- if (cpu->cpu_index < plugin.scoreboard_alloc_size) {
+ size_t scoreboard_size = plugin.scoreboard_alloc_size;
+ bool need_realloc = false;
+
+ if (cpu->cpu_index < scoreboard_size) {
return;
}
- bool need_realloc = FALSE;
- while (cpu->cpu_index >= plugin.scoreboard_alloc_size) {
- plugin.scoreboard_alloc_size *= 2;
- need_realloc = TRUE;
+ while (cpu->cpu_index >= scoreboard_size) {
+ scoreboard_size *= 2;
+ need_realloc = true;
}
+ if (!need_realloc) {
+ return;
+ }
- if (!need_realloc || QLIST_EMPTY(&plugin.scoreboards)) {
- /* nothing to do, we just updated sizes for future scoreboards */
+ if (QLIST_EMPTY(&plugin.scoreboards)) {
+ /* just update size for future scoreboards */
+ plugin.scoreboard_alloc_size = scoreboard_size;
return;
}
+ /*
+ * A scoreboard creation/deletion might be in progress. If a new vcpu is
+ * initialized at the same time, we are safe, as the new
+ * plugin.scoreboard_alloc_size was not yet written.
+ */
+ qemu_rec_mutex_unlock(&plugin.lock);
+
/* cpus must be stopped, as tb might still use an existing scoreboard. */
start_exclusive();
- struct qemu_plugin_scoreboard *score;
- QLIST_FOREACH(score, &plugin.scoreboards, entry) {
- g_array_set_size(score->data, plugin.scoreboard_alloc_size);
+ /* re-acquire lock */
+ qemu_rec_mutex_lock(&plugin.lock);
+ /* in case another vcpu is created between unlock and exclusive section. */
+ if (scoreboard_size > plugin.scoreboard_alloc_size) {
+ struct qemu_plugin_scoreboard *score;
+ QLIST_FOREACH(score, &plugin.scoreboards, entry) {
+ g_array_set_size(score->data, scoreboard_size);
+ }
+ plugin.scoreboard_alloc_size = scoreboard_size;
+ /* force all tb to be flushed, as scoreboard pointers were changed. */
+ tb_flush(cpu);
}
- /* force all tb to be flushed, as scoreboard pointers were changed. */
- tb_flush(cpu);
end_exclusive();
}
--
2.39.2
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, (continued)
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Michael S. Tsirkin, 2024/08/13
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Nicholas Piggin, 2024/08/14
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Michael S. Tsirkin, 2024/08/14
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Alex Bennée, 2024/08/14
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Nicholas Piggin, 2024/08/15
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Michael S. Tsirkin, 2024/08/15
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Nicholas Piggin, 2024/08/15
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Jason Wang, 2024/08/15
- Re: [PATCH v2 16/21] virtio-net: Use replay_schedule_bh_event for bhs that affect machine state, Alex Bennée, 2024/08/16
[PATCH v2 15/21] chardev: set record/replay on the base device of a muxed device, Alex Bennée, 2024/08/13
[PATCH v2 21/21] plugins: fix race condition with scoreboards,
Alex Bennée <=
[PATCH v2 10/21] scripts/replay-dump.py: rejig decoders in event number order, Alex Bennée, 2024/08/13
[PATCH v2 17/21] virtio-net: Use virtual time for RSC timers, Alex Bennée, 2024/08/13
[PATCH v2 19/21] docs: Fix some typos (found by typos) and grammar issues, Alex Bennée, 2024/08/13
[PATCH v2 18/21] savevm: Fix load_snapshot error path crash, Alex Bennée, 2024/08/13
[PATCH v2 20/21] docs/devel: update tcg-plugins page, Alex Bennée, 2024/08/13