qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 4/5] tcg: reorder removal from lists in tb_phys_inva


From: sergey . fedorov
Subject: [Qemu-devel] [PATCH 4/5] tcg: reorder removal from lists in tb_phys_invalidate
Date: Thu, 17 Mar 2016 16:46:21 +0300

From: Paolo Bonzini <address@hidden>

First the translation block is invalidated, for which a simple write
to tb->pc is enough.  This means that cpu-exec will not pick up anymore
the block, though it may still execute it through chained jumps.  This
also replaces the NULLing out of the pointer in the CPUs' local cache.

Then the chained jumps are removed, meaning that CPUs will only execute
the translation block once after this point.

Finally, the TB is removed from the per-page list and the phys-hash
bucket to clean up the data structure.

This has no effect for now, but it will be the right order when tb_find_fast
is moved outside the tb_lock.

Signed-off-by: Paolo Bonzini <address@hidden>
Signed-off-by: Sergey Fedorov <address@hidden>
---
 translate-all.c | 56 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index a1ac9841de48..1db5a914d9a3 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -966,40 +966,21 @@ static inline void tb_jmp_remove(TranslationBlock *tb, 
int n)
 /* invalidate one TB */
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 {
-    CPUState *cpu;
     PageDesc *p;
     unsigned int h, n1;
+    tb_page_addr_t pc;
     tb_page_addr_t phys_pc;
     TranslationBlock *tb1, *tb2;
 
-    /* remove the TB from the hash list */
-    phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
-    h = tb_phys_hash_func(phys_pc);
-    tb_hash_remove(&tcg_ctx.tb_ctx.tb_phys_hash[h], tb);
-
-    /* remove the TB from the page list */
-    if (tb->page_addr[0] != page_addr) {
-        p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
-        tb_page_remove(&p->first_tb, tb);
-        invalidate_page_bitmap(p);
-    }
-    if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
-        p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
-        tb_page_remove(&p->first_tb, tb);
-        invalidate_page_bitmap(p);
-    }
-
-    tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
-
-    /* remove the TB from the hash list */
-    h = tb_jmp_cache_hash_func(tb->pc);
-    CPU_FOREACH(cpu) {
-        if (cpu->tb_jmp_cache[h] == tb) {
-            cpu->tb_jmp_cache[h] = NULL;
-        }
-    }
+    /* First invalidate the translation block.  CPUs will not use it anymore
+     * from their local caches.
+     */
+    pc = tb->pc;
+    tb->pc = -1;
 
-    /* suppress this TB from the two jump lists */
+    /* Then suppress this TB from the two jump lists.  CPUs will not jump
+     * anymore into this translation block.
+     */
     tb_jmp_remove(tb, 0);
     tb_jmp_remove(tb, 1);
 
@@ -1017,6 +998,25 @@ void tb_phys_invalidate(TranslationBlock *tb, 
tb_page_addr_t page_addr)
     }
     tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
 
+    /* Now remove the TB from the hash list, so that tb_find_slow
+     * cannot find it anymore.
+     */
+    phys_pc = tb->page_addr[0] + (pc & ~TARGET_PAGE_MASK);
+    h = tb_phys_hash_func(phys_pc);
+    tb_hash_remove(&tcg_ctx.tb_ctx.tb_phys_hash[h], tb);
+
+    /* remove the TB from the page list */
+    if (tb->page_addr[0] != page_addr) {
+        p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
+        tb_page_remove(&p->first_tb, tb);
+        invalidate_page_bitmap(p);
+    }
+    if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
+        p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
+        tb_page_remove(&p->first_tb, tb);
+        invalidate_page_bitmap(p);
+    }
+
     tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
 }
 
-- 
2.7.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]