On 10/31/22 22:07, Ilya Leoshkevich wrote:
@@ -1580,15 +1580,13 @@ void tcg_flush_jmp_cache(CPUState *cpu)
  {
      CPUJumpCache *jc = cpu->tb_jmp_cache;
- if (likely(jc)) {
-        for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
-            qatomic_set(&jc->array[i].tb, NULL);
-        }
-    } else {
-        /* This should happen once during realize, and thus never race. */
-        jc = g_new0(CPUJumpCache, 1);
-        jc = qatomic_xchg(&cpu->tb_jmp_cache, jc);
-        assert(jc == NULL);
+    /* During early initialization, the cache may not yet be allocated. */
+    if (unlikely(jc == NULL)) {
+        return;
+    }

We can hit this condition in qemu-system with the following call
chain:

     tcg_flush_jmp_cache
     tlb_flush_by_mmuidx_async_work
     listener_add_address_space
     memory_listener_register
     cpu_address_space_init
     tcg_cpu_realizefn
     cpu_exec_realizefn
     x86_cpu_realizefn

I'm wondering if we can avoid having to think of early initialization
when dealing with tb_jmp_cache by initializing it as early as possible?
I don't think swapping accel_cpu_realizefn() and tcg_exec_realizefn()
is going to work (though I haven't tried it), but what about splitting
tcg_exec_realizefn() in two and calling the half that initializes
tb_jmp_cache before accel_cpu_realizefn()?

I thought about that, but couldn't bring myself to split out a third tcg piece 
of init.


r~


Reply via email to