Re: [PATCH 2/2] KVM: PPC: Book3S HV: Optimise TLB flushing when a vcpu moves between threads in a core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Nicholas Piggin <npiggin@xxxxxxxxx> writes:

> As explained in the comment, there is no need to flush TLBs on all
> threads in a core when a vcpu moves between threads in the same core.
>
> Thread migrations can be a significant proportion of vcpu migrations,
> so this can help reduce the TLB flushing and IPI traffic.
>
> Signed-off-by: Nicholas Piggin <npiggin@xxxxxxxxx>
> ---
> I believe we can do this and have the TLB coherency correct as per
> the architecture, but would appreciate someone else verifying my
> thinking.
>
> Thanks,
> Nick
>
>  arch/powerpc/kvm/book3s_hv.c | 28 ++++++++++++++++++++++++++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 752daf43f780..53d0cbfe5933 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -2584,7 +2584,7 @@ static void kvmppc_release_hwthread(int cpu)
>  	tpaca->kvm_hstate.kvm_split_mode = NULL;
>  }
>  
> -static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu)
> +static void radix_flush_cpu(struct kvm *kvm, int cpu, bool core, struct kvm_vcpu *vcpu)
>  {

Can we rename 'core' to something like 'core_sched'  or 'within_core' 

>  	struct kvm_nested_guest *nested = vcpu->arch.nested;
>  	cpumask_t *cpu_in_guest;
> @@ -2599,6 +2599,14 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu)
>  		cpu_in_guest = &kvm->arch.cpu_in_guest;
>  	}
>

and do
      if (core_sched) {

> +	if (!core) {
> +		cpumask_set_cpu(cpu, need_tlb_flush);
> +		smp_mb();
> +		if (cpumask_test_cpu(cpu, cpu_in_guest))
> +			smp_call_function_single(cpu, do_nothing, NULL, 1);
> +		return;
> +	}
> +
>  	cpu = cpu_first_thread_sibling(cpu);
>  	for (i = 0; i < threads_per_core; ++i)
>  		cpumask_set_cpu(cpu + i, need_tlb_flush);
> @@ -2655,7 +2663,23 @@ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu)
>  		if (prev_cpu < 0)
>  			return; /* first run */
>  
> -		radix_flush_cpu(kvm, prev_cpu, vcpu);
> +		/*
> +		 * If changing cores, all threads on the old core should
> +		 * flush, because TLBs can be shared between threads. More
> +		 * precisely, the thread we previously ran on should be
> +		 * flushed, and the thread to first run a vcpu on the old
> +		 * core should flush, but we don't keep enough information
> +		 * around to track that, so we flush all.
> +		 *
> +		 * If changing threads in the same core, only the old thread
> +		 * need be flushed.
> +		 */
> +		if (cpu_first_thread_sibling(prev_cpu) !=
> +		    cpu_first_thread_sibling(pcpu))
> +			radix_flush_cpu(kvm, prev_cpu, true, vcpu);
> +		else
> +			radix_flush_cpu(kvm, prev_cpu, false, vcpu);
> +
>  	}
>  }
>  
> -- 
> 2.23.0



[Index of Archives]     [KVM Development]     [KVM ARM]     [KVM ia64]     [Linux Virtualization]     [Linux USB Devel]     [Linux Video]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux