From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39959) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZTgbp-0003n7-Cg for qemu-devel@nongnu.org; Sun, 23 Aug 2015 21:31:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZTgbm-0004bj-6p for qemu-devel@nongnu.org; Sun, 23 Aug 2015 21:31:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53570) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZTgbl-0004bc-Vi for qemu-devel@nongnu.org; Sun, 23 Aug 2015 21:31:34 -0400 References: <1440375847-17603-1-git-send-email-cota@braap.org> <1440375847-17603-36-git-send-email-cota@braap.org> From: Paolo Bonzini Message-ID: <55DA737D.6040509@redhat.com> Date: Sun, 23 Aug 2015 18:29:33 -0700 MIME-Version: 1.0 In-Reply-To: <1440375847-17603-36-git-send-email-cota@braap.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC 35/38] cputlb: use cpu_tcg_sched_work for tlb_flush_all List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Emilio G. Cota" , qemu-devel@nongnu.org, mttcg@greensocs.com Cc: guillaume.delbergue@greensocs.com, alex.bennee@linaro.org, mark.burton@greensocs.com, a.rigo@virtualopensystems.com, Frederic Konrad On 23/08/2015 17:24, Emilio G. Cota wrote: > Signed-off-by: Emilio G. Cota > --- > cputlb.c | 41 +++++++++++------------------------------ > 1 file changed, 11 insertions(+), 30 deletions(-) As suggested by me and Peter, synchronization on TLB flushes should be arch-specific. CPUs can halt on a dmb if they have pending TLB flush requests on other CPUs, and the CPU can be woken up from the run_on_cpu callback with something like: if (--caller_cpu->pending_tlb_flush_request) { caller_cpu->interrupt_request |= CPU_INTERRUPT_TLB_DONE; qemu_cpu_kick(caller_cpu); } ... static bool arm_cpu_has_work(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); return !cpu->pending_tlb_flush_request && !cpu->powered_off && cs->interrupt_request & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TLB_DONE); } Paolo > diff --git a/cputlb.c b/cputlb.c > index 1b3673e..d81a4eb 100644 > --- a/cputlb.c > +++ b/cputlb.c > @@ -73,43 +73,24 @@ void tlb_flush(CPUState *cpu, int flush_global) > tlb_flush_count++; > } > > -struct TLBFlushParams { > - CPUState *cpu; > - int flush_global; > -}; > - > -static void tlb_flush_async_work(void *opaque) > +static void __tlb_flush_all(void *arg) > { > - struct TLBFlushParams *params = opaque; > + CPUState *cpu; > + int flush_global = *(int *)arg; > > - tlb_flush(params->cpu, params->flush_global); > - g_free(params); > + CPU_FOREACH(cpu) { > + tlb_flush(cpu, flush_global); > + } > + g_free(arg); > } > > void tlb_flush_all(int flush_global) > { > - CPUState *cpu; > - struct TLBFlushParams *params; > + int *arg = g_malloc(sizeof(*arg)); > > -#if 0 /* MTTCG */ > - CPU_FOREACH(cpu) { > - tlb_flush(cpu, flush_global); > - } > -#else > - CPU_FOREACH(cpu) { > - if (qemu_cpu_is_self(cpu)) { > - /* async_run_on_cpu handle this case but this just avoid a malloc > - * here. > - */ > - tlb_flush(cpu, flush_global); > - } else { > - params = g_malloc(sizeof(struct TLBFlushParams)); > - params->cpu = cpu; > - params->flush_global = flush_global; > - async_run_on_cpu(cpu, tlb_flush_async_work, params); > - } > - } > -#endif /* MTTCG */ > + *arg = flush_global; > + tb_lock(); > + cpu_tcg_sched_work(current_cpu, __tlb_flush_all, arg); > } > > static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) >