From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Nicholas Piggin <npiggin@gmail.com>
Subject: [PATCH v4 43/53] KVM: PPC: Book3S HV P9: Avoid tlbsync sequence on radix guest exit
Date: Tue, 23 Nov 2021 19:52:21 +1000 [thread overview]
Message-ID: <20211123095231.1036501-44-npiggin@gmail.com> (raw)
In-Reply-To: <20211123095231.1036501-1-npiggin@gmail.com>
Use the existing TLB flushing logic to IPI the previous CPU and run the
necessary barriers before running a guest vCPU on a new physical CPU,
to do the necessary radix GTSE barriers for handling the case of an
interrupted guest tlbie sequence.
This requires the vCPU TLB flush sequence that is currently just done
on one thread, to be expanded to ensure the other threads execute a
ptesync, because causing them to exit the guest will no longer cause a
ptesync by itself.
This results in more IPIs than the TLB flush logic requires, but it's
a significant win for common case scheduling when the vCPU remains on
the same physical CPU.
This saves about 520 cycles (nearly 10%) on a guest entry+exit micro
benchmark on a POWER9.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_hv.c | 48 +++++++++++++++++++++------
arch/powerpc/kvm/book3s_hv_p9_entry.c | 48 +++++++++++++++------------
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 6 ----
3 files changed, 65 insertions(+), 37 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 9da27f19a697..df4e3f88398d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3002,29 +3002,54 @@ static void kvmppc_release_hwthread(int cpu)
static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu)
{
struct kvm_nested_guest *nested = vcpu->arch.nested;
- cpumask_t *cpu_in_guest;
+ cpumask_t *cpu_in_guest, *need_tlb_flush;
int i;
- cpu = cpu_first_tlb_thread_sibling(cpu);
if (nested) {
- cpumask_set_cpu(cpu, &nested->need_tlb_flush);
+ need_tlb_flush = &nested->need_tlb_flush;
cpu_in_guest = &nested->cpu_in_guest;
} else {
- cpumask_set_cpu(cpu, &kvm->arch.need_tlb_flush);
+ need_tlb_flush = &kvm->arch.need_tlb_flush;
cpu_in_guest = &kvm->arch.cpu_in_guest;
}
+
+ cpu = cpu_first_tlb_thread_sibling(cpu);
+ for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu);
+ i += cpu_tlb_thread_sibling_step())
+ cpumask_set_cpu(i, need_tlb_flush);
+
/*
* Make sure setting of bit in need_tlb_flush precedes
* testing of cpu_in_guest bits. The matching barrier on
* the other side is the first smp_mb() in kvmppc_run_core().
*/
smp_mb();
+
for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu);
i += cpu_tlb_thread_sibling_step())
if (cpumask_test_cpu(i, cpu_in_guest))
smp_call_function_single(i, do_nothing, NULL, 1);
}
+static void do_migrate_away_vcpu(void *arg)
+{
+ struct kvm_vcpu *vcpu = arg;
+ struct kvm *kvm = vcpu->kvm;
+
+ /*
+ * If the guest has GTSE, it may execute tlbie, so do a eieio; tlbsync;
+ * ptesync sequence on the old CPU before migrating to a new one, in
+ * case we interrupted the guest between a tlbie ; eieio ;
+ * tlbsync; ptesync sequence.
+ *
+ * Otherwise, ptesync is sufficient for ordering tlbiel sequences.
+ */
+ if (kvm->arch.lpcr & LPCR_GTSE)
+ asm volatile("eieio; tlbsync; ptesync");
+ else
+ asm volatile("ptesync");
+}
+
static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu)
{
struct kvm_nested_guest *nested = vcpu->arch.nested;
@@ -3048,14 +3073,17 @@ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu)
* can move around between pcpus. To cope with this, when
* a vcpu moves from one pcpu to another, we need to tell
* any vcpus running on the same core as this vcpu previously
- * ran to flush the TLB. The TLB is shared between threads,
- * so we use a single bit in .need_tlb_flush for all 4 threads.
+ * ran to flush the TLB.
*/
if (prev_cpu != pcpu) {
- if (prev_cpu >= 0 &&
- cpu_first_tlb_thread_sibling(prev_cpu) !=
- cpu_first_tlb_thread_sibling(pcpu))
- radix_flush_cpu(kvm, prev_cpu, vcpu);
+ if (prev_cpu >= 0) {
+ if (cpu_first_tlb_thread_sibling(prev_cpu) !=
+ cpu_first_tlb_thread_sibling(pcpu))
+ radix_flush_cpu(kvm, prev_cpu, vcpu);
+
+ smp_call_function_single(prev_cpu,
+ do_migrate_away_vcpu, vcpu, 1);
+ }
if (nested)
nested->prev_cpu[vcpu->arch.nested_vcpu_id] = pcpu;
else
diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c b/arch/powerpc/kvm/book3s_hv_p9_entry.c
index d0216d32ec91..9e899c813803 100644
--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
+++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
@@ -670,26 +670,41 @@ static void check_need_tlb_flush(struct kvm *kvm, int pcpu,
struct kvm_nested_guest *nested)
{
cpumask_t *need_tlb_flush;
-
- /*
- * On POWER9, individual threads can come in here, but the
- * TLB is shared between the 4 threads in a core, hence
- * invalidating on one thread invalidates for all.
- * Thus we make all 4 threads use the same bit.
- */
- pcpu = cpu_first_tlb_thread_sibling(pcpu);
+ bool all_set = true;
+ int i;
if (nested)
need_tlb_flush = &nested->need_tlb_flush;
else
need_tlb_flush = &kvm->arch.need_tlb_flush;
- if (cpumask_test_cpu(pcpu, need_tlb_flush)) {
- flush_guest_tlb(kvm);
+ if (likely(!cpumask_test_cpu(pcpu, need_tlb_flush)))
+ return;
- /* Clear the bit after the TLB flush */
- cpumask_clear_cpu(pcpu, need_tlb_flush);
+ /*
+ * Individual threads can come in here, but the TLB is shared between
+ * the 4 threads in a core, hence invalidating on one thread
+ * invalidates for all, so only invalidate the first time (if all bits
+ * were set. The others must still execute a ptesync.
+ *
+ * If a race occurs and two threads do the TLB flush, that is not a
+ * problem, just sub-optimal.
+ */
+ for (i = cpu_first_tlb_thread_sibling(pcpu);
+ i <= cpu_last_tlb_thread_sibling(pcpu);
+ i += cpu_tlb_thread_sibling_step()) {
+ if (!cpumask_test_cpu(i, need_tlb_flush)) {
+ all_set = false;
+ break;
+ }
}
+ if (all_set)
+ flush_guest_tlb(kvm);
+ else
+ asm volatile("ptesync" ::: "memory");
+
+ /* Clear the bit after the TLB flush */
+ cpumask_clear_cpu(pcpu, need_tlb_flush);
}
int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpcr, u64 *tb)
@@ -1109,15 +1124,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
local_paca->kvm_hstate.in_guest = KVM_GUEST_MODE_NONE;
- if (kvm_is_radix(kvm)) {
- /*
- * Since this is radix, do a eieio; tlbsync; ptesync sequence
- * in case we interrupted the guest between a tlbie and a
- * ptesync.
- */
- asm volatile("eieio; tlbsync; ptesync");
- }
-
/*
* cp_abort is required if the processor supports local copy-paste
* to clear the copy buffer that was under control of the guest.
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 2c1f3c6e72d1..2257fb18cb72 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -55,12 +55,6 @@ static int global_invalidates(struct kvm *kvm)
smp_wmb();
cpumask_setall(&kvm->arch.need_tlb_flush);
cpu = local_paca->kvm_hstate.kvm_vcore->pcpu;
- /*
- * On POWER9, threads are independent but the TLB is shared,
- * so use the bit for the first thread to represent the core.
- */
- if (cpu_has_feature(CPU_FTR_ARCH_300))
- cpu = cpu_first_tlb_thread_sibling(cpu);
cpumask_clear_cpu(cpu, &kvm->arch.need_tlb_flush);
}
--
2.23.0
next prev parent reply other threads:[~2021-11-23 10:21 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-23 9:51 [PATCH v4 00/53] KVM: PPC: Book3S HV P9: entry/exit optimisations Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 01/53] powerpc/64s: Remove WORT SPR from POWER9/10 (take 2) Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 02/53] powerpc/64s: guard optional TIDR SPR with CPU ftr test Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 03/53] KMV: PPC: Book3S HV P9: Use set_dec to set decrementer to host Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 04/53] KVM: PPC: Book3S HV P9: Use host timer accounting to avoid decrementer read Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 05/53] KVM: PPC: Book3S HV P9: Use large decrementer for HDEC Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 06/53] KVM: PPC: Book3S HV P9: Reduce mftb per guest entry/exit Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 07/53] powerpc/time: add API for KVM to re-arm the host timer/decrementer Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 08/53] KVM: PPC: Book3S HV: POWER10 enable HAIL when running radix guests Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 09/53] powerpc/64s: Keep AMOR SPR a constant ~0 at runtime Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 10/53] KVM: PPC: Book3S HV: Don't always save PMU for guest capable of nesting Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 11/53] powerpc/64s: Always set PMU control registers to frozen/disabled when not in use Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 12/53] powerpc/64s: Implement PMU override command line option Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 13/53] KVM: PPC: Book3S HV P9: Implement PMU save/restore in C Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 14/53] KVM: PPC: Book3S HV P9: Factor PMU save/load into context switch functions Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 15/53] KVM: PPC: Book3S HV P9: Demand fault PMU SPRs when marked not inuse Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 16/53] KVM: PPC: Book3S HV P9: Factor out yield_count increment Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 17/53] KVM: PPC: Book3S HV: CTRL SPR does not require read-modify-write Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 18/53] KVM: PPC: Book3S HV P9: Move SPRG restore to restore_p9_host_os_sprs Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 19/53] KVM: PPC: Book3S HV P9: Reduce mtmsrd instructions required to save host SPRs Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 20/53] KVM: PPC: Book3S HV P9: Improve mtmsrd scheduling by delaying MSR[EE] disable Nicholas Piggin
2021-11-23 9:51 ` [PATCH v4 21/53] KVM: PPC: Book3S HV P9: Add kvmppc_stop_thread to match kvmppc_start_thread Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 22/53] KVM: PPC: Book3S HV: Change dec_expires to be relative to guest timebase Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 23/53] KVM: PPC: Book3S HV P9: Move TB updates Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 24/53] KVM: PPC: Book3S HV P9: Optimise timebase reads Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 25/53] KVM: PPC: Book3S HV P9: Avoid SPR scoreboard stalls Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 26/53] KVM: PPC: Book3S HV P9: Only execute mtSPR if the value changed Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 27/53] KVM: PPC: Book3S HV P9: Juggle SPR switching around Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 28/53] KVM: PPC: Book3S HV P9: Move vcpu register save/restore into functions Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 29/53] KVM: PPC: Book3S HV P9: Move host OS save/restore functions to built-in Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 30/53] KVM: PPC: Book3S HV P9: Move nested guest entry into its own function Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 31/53] KVM: PPC: Book3S HV P9: Move remaining SPR and MSR access into low level entry Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 32/53] KVM: PPC: Book3S HV P9: Implement TM fastpath for guest entry/exit Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 33/53] KVM: PPC: Book3S HV P9: Switch PMU to guest as late as possible Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 34/53] KVM: PPC: Book3S HV P9: Restrict DSISR canary workaround to processors that require it Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 35/53] KVM: PPC: Book3S HV P9: More SPR speed improvements Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 36/53] KVM: PPC: Book3S HV P9: Demand fault EBB facility registers Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 37/53] KVM: PPC: Book3S HV P9: Demand fault TM " Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 38/53] KVM: PPC: Book3S HV P9: Use Linux SPR save/restore to manage some host SPRs Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 39/53] KVM: PPC: Book3S HV P9: Comment and fix MMU context switching code Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 40/53] KVM: PPC: Book3S HV P9: Test dawr_enabled() before saving host DAWR SPRs Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 41/53] KVM: PPC: Book3S HV P9: Don't restore PSSCR if not needed Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 42/53] KVM: PPC: Book3S HV: Split P8 from P9 path guest vCPU TLB flushing Nicholas Piggin
2021-11-23 9:52 ` Nicholas Piggin [this message]
2021-11-23 9:52 ` [PATCH v4 44/53] KVM: PPC: Book3S HV Nested: Avoid extra mftb() in nested entry Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 45/53] KVM: PPC: Book3S HV P9: Improve mfmsr performance on entry Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 46/53] KVM: PPC: Book3S HV P9: Optimise hash guest SLB saving Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 47/53] KVM: PPC: Book3S HV P9: Avoid changing MSR[RI] in entry and exit Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 48/53] KVM: PPC: Book3S HV P9: Add unlikely annotation for !mmu_ready Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 49/53] KVM: PPC: Book3S HV P9: Avoid cpu_in_guest atomics on entry and exit Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 50/53] KVM: PPC: Book3S HV P9: Remove most of the vcore logic Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 51/53] KVM: PPC: Book3S HV P9: Tidy kvmppc_create_dtl_entry Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 52/53] KVM: PPC: Book3S HV P9: Stop using vc->dpdes Nicholas Piggin
2021-11-23 9:52 ` [PATCH v4 53/53] KVM: PPC: Book3S HV P9: Remove subcore HMI handling Nicholas Piggin
2021-11-25 9:38 ` [PATCH v4 00/53] KVM: PPC: Book3S HV P9: entry/exit optimisations Michael Ellerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211123095231.1036501-44-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).