From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z8Vy4-0002Wd-Ux for qemu-devel@nongnu.org; Fri, 26 Jun 2015 11:55:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z8Vy1-0004qg-KG for qemu-devel@nongnu.org; Fri, 26 Jun 2015 11:55:04 -0400 Received: from greensocs.com ([193.104.36.180]:56747) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z8Vy1-0004pU-7M for qemu-devel@nongnu.org; Fri, 26 Jun 2015 11:55:01 -0400 Message-ID: <558D75D0.6060906@greensocs.com> Date: Fri, 26 Jun 2015 17:54:56 +0200 From: Frederic Konrad MIME-Version: 1.0 References: <1435330053-18733-1-git-send-email-fred.konrad@greensocs.com> <1435330053-18733-16-git-send-email-fred.konrad@greensocs.com> <558D6C7E.6020905@redhat.com> In-Reply-To: <558D6C7E.6020905@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC PATCH V6 15/18] cpu: introduce tlb_flush*_all. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , qemu-devel@nongnu.org, mttcg@greensocs.com Cc: peter.maydell@linaro.org, a.spyridakis@virtualopensystems.com, mark.burton@greensocs.com, agraf@suse.de, alistair.francis@xilinx.com, guillaume.delbergue@greensocs.com, alex.bennee@linaro.org On 26/06/2015 17:15, Paolo Bonzini wrote: > > On 26/06/2015 16:47, fred.konrad@greensocs.com wrote: >> + 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); > Shouldn't this be synchronous (which you cannot do straightforwardly > because of deadlocks---hence the need to hook cpu_has_work as discussed > earlier)? > > Paolo > I think it doesn't requires to be synchronous as each VCPUs only clear it's own tlb here: void tlb_flush(CPUState *cpu, int flush_global) { CPUArchState *env = cpu->env_ptr; #if defined(DEBUG_TLB) printf("tlb_flush:\n"); #endif /* must reset current TB so that interrupts cannot modify the links while we are modifying them */ cpu->current_tb = NULL; memset(env->tlb_table, -1, sizeof(env->tlb_table)); memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table)); memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache)); env->vtlb_index = 0; env->tlb_flush_addr = -1; env->tlb_flush_mask = 0; tlb_flush_count++; } So what happen is: An arm instruction want to clear tlb of all VCPUs eg: IS version of TLBIALL. The VCPU which execute the TLBIALL_IS can't flush tlb of other VCPU. It will just ask all VCPU thread to exit and to do tlb_flush hence the async_work. Maybe the big issue might be memory barrier instruction here which I didn't checked. Fred >> + } >> + }