From: Nicholas Piggin <npiggin@gmail.com>
To: kvm-ppc@vger.kernel.org
Cc: Nicholas Piggin <npiggin@gmail.com>, linuxppc-dev@lists.ozlabs.org
Subject: [RFC PATCH 5/5] KVM: PPC: Book3S HV: Radix do not clear partition scoped page table when page fault races with other vCPUs.
Date: Tue, 10 Apr 2018 22:48:42 +1000 [thread overview]
Message-ID: <20180410124842.30184-6-npiggin@gmail.com> (raw)
In-Reply-To: <20180410124842.30184-1-npiggin@gmail.com>
KVM with an SMP radix guest can get into storms of page faults and
tlbies due to the partition scopd page tables being invalidated and
TLB flushed if they were found to race with another page fault that
set them up.
This tends to cause vCPUs to pile up if several hit common addresses,
then page faults will get serialized on common locks, and then they
each invalidate the previous entry and it's long enough before installing
the new entry that will cause more CPUs to hit page faults and they will
invalidate that new entry.
There doesn't seem to be a need to invalidate in the case of an existing
entry. This solves the tlbie storms.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_64_mmu_radix.c | 39 +++++++++++++++-----------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index dab6b622011c..4af177d24f6c 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -243,6 +243,7 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
pmd = pmd_offset(pud, gpa);
if (pmd_is_leaf(*pmd)) {
unsigned long lgpa = gpa & PMD_MASK;
+ pte_t old_pte = *pmdp_ptep(pmd);
/*
* If we raced with another CPU which has just put
@@ -252,18 +253,17 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
ret = -EAGAIN;
goto out_unlock;
}
- /* Valid 2MB page here already, remove it */
- old = kvmppc_radix_update_pte(kvm, pmdp_ptep(pmd),
- ~0UL, 0, lgpa, PMD_SHIFT);
- kvmppc_radix_tlbie_page(kvm, lgpa, PMD_SHIFT);
- if (old & _PAGE_DIRTY) {
- unsigned long gfn = lgpa >> PAGE_SHIFT;
- struct kvm_memory_slot *memslot;
- memslot = gfn_to_memslot(kvm, gfn);
- if (memslot && memslot->dirty_bitmap)
- kvmppc_update_dirty_map(memslot,
- gfn, PMD_SIZE);
+ WARN_ON_ONCE(pte_pfn(old_pte) != pte_pfn(pte));
+ if (pte_val(old_pte) == pte_val(pte)) {
+ ret = -EAGAIN;
+ goto out_unlock;
}
+
+ /* Valid 2MB page here already, remove it */
+ kvmppc_radix_update_pte(kvm, pmdp_ptep(pmd),
+ 0, pte_val(pte), lgpa, PMD_SHIFT);
+ ret = 0;
+ goto out_unlock;
} else if (level == 1 && !pmd_none(*pmd)) {
/*
* There's a page table page here, but we wanted
@@ -274,6 +274,8 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
goto out_unlock;
}
if (level == 0) {
+ pte_t old_pte;
+
if (pmd_none(*pmd)) {
if (!new_ptep)
goto out_unlock;
@@ -281,13 +283,16 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
new_ptep = NULL;
}
ptep = pte_offset_kernel(pmd, gpa);
- if (pte_present(*ptep)) {
+ old_pte = *ptep;
+ if (pte_present(old_pte)) {
/* PTE was previously valid, so invalidate it */
- old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_PRESENT,
- 0, gpa, 0);
- kvmppc_radix_tlbie_page(kvm, gpa, 0);
- if (old & _PAGE_DIRTY)
- mark_page_dirty(kvm, gpa >> PAGE_SHIFT);
+ WARN_ON_ONCE(pte_pfn(old_pte) != pte_pfn(pte));
+ if (pte_val(old_pte) == pte_val(pte)) {
+ ret = -EAGAIN;
+ goto out_unlock;
+ }
+ kvmppc_radix_update_pte(kvm, ptep, 0,
+ pte_val(pte), gpa, 0);
}
kvmppc_radix_set_pte_at(kvm, gpa, ptep, pte);
} else {
--
2.17.0
prev parent reply other threads:[~2018-04-10 12:49 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-10 12:48 [RFC PATCH 0/5] KVM TLB flushing improvements Nicholas Piggin
2018-04-10 12:48 ` [RFC PATCH 1/5] powerpc/64s/mm: Implement LPID based TLB flushes to be used by KVM Nicholas Piggin
2018-04-10 12:48 ` [RFC PATCH 2/5] KVM: PPC: Book3S HV: kvmppc_radix_tlbie_page use Linux flush function Nicholas Piggin
2018-04-10 12:48 ` [RFC PATCH 3/5] KVM: PPC: Book3S HV: kvmhv_p9_set_lpcr " Nicholas Piggin
2018-04-10 12:48 ` [RFC PATCH 4/5] KVM: PPC: Book3S HV: handle need_tlb_flush in C before low-level guest entry Nicholas Piggin
2018-04-11 1:32 ` Benjamin Herrenschmidt
2018-04-11 2:19 ` Nicholas Piggin
2018-04-15 5:28 ` Nicholas Piggin
2018-04-10 12:48 ` Nicholas Piggin [this message]
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=20180410124842.30184-6-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=kvm-ppc@vger.kernel.org \
--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).