From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47265) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCUrJ-0008U0-9a for qemu-devel@nongnu.org; Tue, 07 Jul 2015 11:32:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZCUrF-0002Ih-0I for qemu-devel@nongnu.org; Tue, 07 Jul 2015 11:32:33 -0400 Received: from mail-wg0-f52.google.com ([74.125.82.52]:35754) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCUrE-0002Ib-Nz for qemu-devel@nongnu.org; Tue, 07 Jul 2015 11:32:28 -0400 Received: by wgjx7 with SMTP id x7so171312655wgj.2 for ; Tue, 07 Jul 2015 08:32:28 -0700 (PDT) References: <1435330053-18733-1-git-send-email-fred.konrad@greensocs.com> <1435330053-18733-15-git-send-email-fred.konrad@greensocs.com> From: Alex =?utf-8?Q?Benn=C3=A9e?= In-reply-to: <1435330053-18733-15-git-send-email-fred.konrad@greensocs.com> Date: Tue, 07 Jul 2015 16:32:25 +0100 Message-ID: <87fv509e5y.fsf@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [RFC PATCH V6 14/18] add a callback when tb_invalidate is called. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: fred.konrad@greensocs.com Cc: mttcg@listserver.greensocs.com, peter.maydell@linaro.org, a.spyridakis@virtualopensystems.com, mark.burton@greensocs.com, agraf@suse.de, qemu-devel@nongnu.org, guillaume.delbergue@greensocs.com, pbonzini@redhat.com, alistair.francis@xilinx.com fred.konrad@greensocs.com writes: > From: KONRAD Frederic > > Instead of doing the jump cache invalidation directly in tb_invalidate delay it > after the exit so we don't have an other CPU trying to execute the code being > invalidated. > > Signed-off-by: KONRAD Frederic > --- > translate-all.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 59 insertions(+), 2 deletions(-) > > diff --git a/translate-all.c b/translate-all.c > index ade2269..468648d 100644 > --- a/translate-all.c > +++ b/translate-all.c > @@ -61,6 +61,7 @@ > #include "translate-all.h" > #include "qemu/bitmap.h" > #include "qemu/timer.h" > +#include "sysemu/cpus.h" > > //#define DEBUG_TB_INVALIDATE > //#define DEBUG_FLUSH > @@ -966,14 +967,58 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n) > tb_set_jmp_target(tb, n, (uintptr_t)(tb->tc_ptr + tb->tb_next_offset[n])); > } > > +struct CPUDiscardTBParams { > + CPUState *cpu; > + TranslationBlock *tb; > +}; > + > +static void cpu_discard_tb_from_jmp_cache(void *opaque) > +{ > + unsigned int h; > + struct CPUDiscardTBParams *params = opaque; > + > + h = tb_jmp_cache_hash_func(params->tb->pc); > + if (params->cpu->tb_jmp_cache[h] == params->tb) { > + params->cpu->tb_jmp_cache[h] = NULL; > + } > + > + g_free(opaque); > +} > + > +static void tb_invalidate_jmp_remove(void *opaque) > +{ > + TranslationBlock *tb = opaque; > + TranslationBlock *tb1, *tb2; > + unsigned int n1; > + > + /* suppress this TB from the two jump lists */ > + tb_jmp_remove(tb, 0); > + tb_jmp_remove(tb, 1); > + > + /* suppress any remaining jumps to this TB */ > + tb1 = tb->jmp_first; > + for (;;) { > + n1 = (uintptr_t)tb1 & 3; > + if (n1 == 2) { > + break; > + } > + tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3); > + tb2 = tb1->jmp_next[n1]; > + tb_reset_jump(tb1, n1); > + tb1->jmp_next[n1] = NULL; > + tb1 = tb2; > + } > + tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */ > +} > + > /* invalidate one TB */ > void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) > { > CPUState *cpu; > PageDesc *p; > - unsigned int h, n1; > + unsigned int h; > tb_page_addr_t phys_pc; > - TranslationBlock *tb1, *tb2; > + struct CPUDiscardTBParams *params; > > tb_lock(); > > @@ -996,6 +1041,9 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) > > tcg_ctx.tb_ctx.tb_invalidated_flag = 1; > > +#if 0 /*MTTCG*/ > + TranslationBlock *tb1, *tb2; > + unsigned int n1; We may as well bite the bullet and get some build logic in to conditionally build MTTCG (with the aim they will all be eventually). > /* remove the TB from the hash list */ > h = tb_jmp_cache_hash_func(tb->pc); > CPU_FOREACH(cpu) { > @@ -1022,6 +1070,15 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) > tb1 = tb2; > } > tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */ > +#else > + CPU_FOREACH(cpu) { > + params = g_malloc(sizeof(struct CPUDiscardTBParams)); > + params->cpu = cpu; > + params->tb = tb; > + async_run_on_cpu(cpu, cpu_discard_tb_from_jmp_cache, params); > + } > + async_run_safe_work_on_cpu(first_cpu, tb_invalidate_jmp_remove, tb); > +#endif /* MTTCG */ > > tcg_ctx.tb_ctx.tb_phys_invalidate_count++; > tb_unlock(); -- Alex Bennée