[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC 35/38] cputlb: use cpu_tcg_sched_work for tlb_flus
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [RFC 35/38] cputlb: use cpu_tcg_sched_work for tlb_flush_all |
Date: |
Sun, 23 Aug 2015 18:29:33 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 |
On 23/08/2015 17:24, Emilio G. Cota wrote:
> Signed-off-by: Emilio G. Cota <address@hidden>
> ---
> 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)
>
[Qemu-devel] [RFC 34/38] translate-all: use tcg_sched_work for tb_flush, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 19/38] tcg: add tcg_gen_smp_rmb(), Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 22/38] cpu: update interrupt_request atomically, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 31/38] cpu: protect l1_map with tb_lock in full-system mode, Emilio G. Cota, 2015/08/23