[Qemu-devel] [PATCH 11/22] translate-all: exit from tb_phys_invalidate if qht_remove fails

Emilio G. Cota posted 22 patches 8 years, 6 months ago
[Qemu-devel] [PATCH 11/22] translate-all: exit from tb_phys_invalidate if qht_remove fails
Posted by Emilio G. Cota 8 years, 6 months ago
Groundwork for supporting parallel TCG generation.

Once tb_lock goes away, it is conceivable that two (or more) threads
might race while invalidating the same TB. We currently do not
check for this, which means we would wrongly invalidate the same TB
more than once.

Fix this by using qht_remove as the synchronization point; if it fails,
that means the TB has already been invalidated, and therefore there
is nothing left to do in tb_phys_invalidate.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 accel/tcg/translate-all.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 8e5e5b2..0e3d223 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1061,7 +1061,9 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
     h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK,
                      tb->trace_vcpu_dstate);
-    qht_remove(&tb_ctx.htable, tb, h);
+    if (!qht_remove(&tb_ctx.htable, tb, h)) {
+        return;
+    }
 
     /* remove the TB from the page list */
     if (tb->page_addr[0] != page_addr) {
-- 
2.7.4