* [PATCH 0/1] accel/tcg: Retry page_check_range() on itree.start inconsistency
@ 2026-07-06 10:57 Ilya Leoshkevich
2026-07-06 10:57 ` [PATCH 1/1] " Ilya Leoshkevich
0 siblings, 1 reply; 2+ messages in thread
From: Ilya Leoshkevich @ 2026-07-06 10:57 UTC (permalink / raw)
To: Richard Henderson, Paolo Bonzini; +Cc: qemu-devel, Ilya Leoshkevich
Hi,
This is an attempt to improve the vma-pthread test situation sparked by
a bug report by wasmtime project. The patch doesn't fix all issues, but
it definitely makes things better and I think I understand what
particular thread interleaving leads to the issue (details are in the
commit message).
There is at least one other thing that I find suspicious about the
current code: page_check_range() fetches itree.last twice, and indeed,
using qatomic_read() there makes things even better, but still not
perfect, and I still cannot clearly elaborate what is the exact
interleaving with pageflags_set_clear() that causes a problem there, so
I'm not sending that one for now.
Best regards,
Ilya
Ilya Leoshkevich (1):
accel/tcg: Retry page_check_range() on itree.start inconsistency
accel/tcg/user-exec.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH 1/1] accel/tcg: Retry page_check_range() on itree.start inconsistency
2026-07-06 10:57 [PATCH 0/1] accel/tcg: Retry page_check_range() on itree.start inconsistency Ilya Leoshkevich
@ 2026-07-06 10:57 ` Ilya Leoshkevich
0 siblings, 0 replies; 2+ messages in thread
From: Ilya Leoshkevich @ 2026-07-06 10:57 UTC (permalink / raw)
To: Richard Henderson, Paolo Bonzini
Cc: qemu-devel, Ilya Leoshkevich, Alex Crichton, Ulrich Weigand,
qemu-stable
page_check_range() may race with pageflags_set_clear() as follows:
T1 T2
------------------------------------- --------------------------------
p = pageflags_find(start, last);
interval_tree_remove(&p->itree, ...);
p->itree.start = last + 1;
if (start < p->itree.start) {
ret = false;
interval_tree_insert(&p->itree, ...);
leading to errors like
fail indirect write 0x72f0a659aff0 (Bad address)
in vma-pthread test. I am able to reliably reproduce this on a machine
with 32 SMT threads as follows in about 25 seconds:
jobs=32; \
seq "$jobs" | \
time -p parallel \
--jobs="$jobs" \
--halt=now,done=1 \
--ungroup \
'
_={};
while ./qemu-s390x tests/tcg/s390x-linux-user/vma-pthread; do
printf .;
done
'
Also wasmtime project reported a similar failure pattern in their CI [1]
with a similar reproducer [2].
Fix by retrying under a lock. This makes the failure rate go down to
roughly once in 50 seconds.
[1] https://github.com/bytecodealliance/wasmtime/issues/10000
[2] https://gist.github.com/alexcrichton/f14f23a892ffb9df2522754572d51b1c
Reported-by: Alex Crichton <alex@alexcrichton.com>
Reported-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Fixes: 67ff2186b0a4 ("accel/tcg: Use interval tree for user-only page tracking")
Cc: qemu-stable@nongnu.org
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
accel/tcg/user-exec.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 7704e4017dd..b70955697fe 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -510,24 +510,23 @@ bool page_check_range(vaddr start, vaddr len, int flags)
PageFlagsNode *p = pageflags_find(start, last);
int missing;
- if (!p) {
- if (!locked) {
- /*
- * Lockless lookups have false negatives.
- * Retry with the lock held.
- */
- mmap_lock();
- locked = -1;
- p = pageflags_find(start, last);
- }
- if (!p) {
- ret = false; /* entire region invalid */
+ /*
+ * Lockless lookups race with pageflags_set_clear() and may have false
+ * negatives:
+ * - The node pageflags_find() was looking for could have been
+ * temporarily removed and not added back yet.
+ * - pageflags_find() could have found a node which was subsequently
+ * removed and whose itree.start has been adjusted.
+ */
+ if (!p || start < p->itree.start) {
+ if (locked) {
+ ret = false;
break;
}
- }
- if (start < p->itree.start) {
- ret = false; /* initial bytes invalid */
- break;
+ /* Retry with the lock held. */
+ mmap_lock();
+ locked = -1;
+ continue;
}
missing = flags & ~p->flags;
--
2.54.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-06 11:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06 10:57 [PATCH 0/1] accel/tcg: Retry page_check_range() on itree.start inconsistency Ilya Leoshkevich
2026-07-06 10:57 ` [PATCH 1/1] " Ilya Leoshkevich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.