Generate new TBs without holding tb_lock, which should increase scalability when running MTTCG for workloads that generate a lot of code (e.g. booting linux).
XXX: Doesn't work :-) See the commit log from the previous patch. Signed-off-by: Emilio G. Cota <c...@braap.org> --- accel/tcg/cpu-exec.c | 8 +++++++- accel/tcg/translate-all.c | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 54ecae2..47f0882 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -351,6 +351,7 @@ static inline TranslationBlock *tb_find(CPUState *cpu, * single threaded the locks are NOPs. */ mmap_lock(); +#ifdef CONFIG_USER_ONLY tb_lock(); have_tb_lock = true; @@ -362,7 +363,12 @@ static inline TranslationBlock *tb_find(CPUState *cpu, /* if no translated code available, then translate it now */ tb = tb_gen_code(cpu, pc, cs_base, flags, 0); } - +#else + /* tb_gen_code will acquire tb_lock. + * Just for the diff: note that have_tb_lock is local to tb_find! */ + have_tb_lock = true; + tb = tb_gen_code(cpu, pc, cs_base, flags, 0); +#endif mmap_unlock(); } diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 125b1a8..da29bcc 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -878,8 +878,6 @@ static TranslationBlock *tb_alloc(target_ulong pc) { TranslationBlock *tb; - assert_tb_locked(); - tb = tcg_tb_alloc(&tcg_ctx); if (unlikely(tb == NULL)) { return NULL; @@ -1314,7 +1312,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu, #ifdef CONFIG_PROFILER int64_t ti; #endif +#ifdef CONFIG_USER_ONLY assert_memory_lock(); +#endif phys_pc = get_page_addr_code(env, pc); if (use_icount && !(cflags & CF_IGNORE_ICOUNT)) { @@ -1429,6 +1429,20 @@ TranslationBlock *tb_gen_code(CPUState *cpu, if ((pc & TARGET_PAGE_MASK) != virt_page2) { phys_page2 = get_page_addr_code(env, virt_page2); } + if (!have_tb_lock) { + TranslationBlock *t; + + tb_lock(); + /* + * There's a chance that our desired tb has been translated while + * we were translating it. + */ + t = tb_htable_lookup(cpu, pc, cs_base, flags); + if (unlikely(t)) { + /* this is very unlikely so just waste the TB space we just used */ + return t; + } + } /* As long as consistency of the TB stuff is provided by tb_lock in user * mode and is implicit in single-threaded softmmu emulation, no explicit * memory barrier is required before tb_link_page() makes the TB visible -- 2.7.4