kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KVM: x86/mmu: Avoid unnecessary page table allocation in kvm_tdp_mmu_map()
@ 2021-04-29  4:12 Kai Huang
  2021-04-29 16:22 ` Ben Gardon
  0 siblings, 1 reply; 3+ messages in thread
From: Kai Huang @ 2021-04-29  4:12 UTC (permalink / raw)
  To: kvm
  Cc: pbonzini, bgardon, seanjc, vkuznets, wanpengli, jmattson, joro,
	Kai Huang

In kvm_tdp_mmu_map(), while iterating TDP MMU page table entries, it is
possible SPTE has already been frozen by another thread but the frozen
is not done yet, for instance, when another thread is still in middle of
zapping large page.  In this case, the !is_shadow_present_pte() check
for old SPTE in tdp_mmu_for_each_pte() may hit true, and in this case
allocating new page table is unnecessary since tdp_mmu_set_spte_atomic()
later will return false and page table will need to be freed.  Add
is_removed_spte() check before allocating new page table to avoid this.

Signed-off-by: Kai Huang <kai.huang@intel.com>
---
 arch/x86/kvm/mmu/tdp_mmu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 83cbdbe5de5a..84ee1a76a79d 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1009,6 +1009,14 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 		}
 
 		if (!is_shadow_present_pte(iter.old_spte)) {
+			/*
+			 * If SPTE has been forzen by another thread, just
+			 * give up and retry, avoiding unnecessary page table
+			 * allocation and free.
+			 */
+			if (is_removed_spte(iter.old_spte))
+				break;
+
 			sp = alloc_tdp_mmu_page(vcpu, iter.gfn, iter.level);
 			child_pt = sp->spt;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] KVM: x86/mmu: Avoid unnecessary page table allocation in kvm_tdp_mmu_map()
  2021-04-29  4:12 [PATCH] KVM: x86/mmu: Avoid unnecessary page table allocation in kvm_tdp_mmu_map() Kai Huang
@ 2021-04-29 16:22 ` Ben Gardon
  2021-04-29 17:05   ` Paolo Bonzini
  0 siblings, 1 reply; 3+ messages in thread
From: Ben Gardon @ 2021-04-29 16:22 UTC (permalink / raw)
  To: Kai Huang
  Cc: kvm, Paolo Bonzini, Sean Christopherson, Vitaly Kuznetsov,
	Wanpeng Li, Jim Mattson, Joerg Roedel

On Wed, Apr 28, 2021 at 9:12 PM Kai Huang <kai.huang@intel.com> wrote:
>
> In kvm_tdp_mmu_map(), while iterating TDP MMU page table entries, it is
> possible SPTE has already been frozen by another thread but the frozen
> is not done yet, for instance, when another thread is still in middle of
> zapping large page.  In this case, the !is_shadow_present_pte() check
> for old SPTE in tdp_mmu_for_each_pte() may hit true, and in this case
> allocating new page table is unnecessary since tdp_mmu_set_spte_atomic()
> later will return false and page table will need to be freed.  Add
> is_removed_spte() check before allocating new page table to avoid this.
>
> Signed-off-by: Kai Huang <kai.huang@intel.com>

Nice catch!

Reviewed-by: Ben Gardon <bgardon@google.com>

> ---
>  arch/x86/kvm/mmu/tdp_mmu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
> index 83cbdbe5de5a..84ee1a76a79d 100644
> --- a/arch/x86/kvm/mmu/tdp_mmu.c
> +++ b/arch/x86/kvm/mmu/tdp_mmu.c
> @@ -1009,6 +1009,14 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
>                 }
>
>                 if (!is_shadow_present_pte(iter.old_spte)) {
> +                       /*
> +                        * If SPTE has been forzen by another thread, just

frozen

> +                        * give up and retry, avoiding unnecessary page table
> +                        * allocation and free.
> +                        */
> +                       if (is_removed_spte(iter.old_spte))
> +                               break;
> +
>                         sp = alloc_tdp_mmu_page(vcpu, iter.gfn, iter.level);
>                         child_pt = sp->spt;
>
> --
> 2.30.2
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] KVM: x86/mmu: Avoid unnecessary page table allocation in kvm_tdp_mmu_map()
  2021-04-29 16:22 ` Ben Gardon
@ 2021-04-29 17:05   ` Paolo Bonzini
  0 siblings, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2021-04-29 17:05 UTC (permalink / raw)
  To: Ben Gardon, Kai Huang
  Cc: kvm, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li,
	Jim Mattson, Joerg Roedel

On 29/04/21 18:22, Ben Gardon wrote:
> On Wed, Apr 28, 2021 at 9:12 PM Kai Huang <kai.huang@intel.com> wrote:
>>
>> In kvm_tdp_mmu_map(), while iterating TDP MMU page table entries, it is
>> possible SPTE has already been frozen by another thread but the frozen
>> is not done yet, for instance, when another thread is still in middle of
>> zapping large page.  In this case, the !is_shadow_present_pte() check
>> for old SPTE in tdp_mmu_for_each_pte() may hit true, and in this case
>> allocating new page table is unnecessary since tdp_mmu_set_spte_atomic()
>> later will return false and page table will need to be freed.  Add
>> is_removed_spte() check before allocating new page table to avoid this.
>>
>> Signed-off-by: Kai Huang <kai.huang@intel.com>
> 
> Nice catch!
> 
> Reviewed-by: Ben Gardon <bgardon@google.com>

Queued, thanks for the quick review.

Paolo


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-04-29 17:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-29  4:12 [PATCH] KVM: x86/mmu: Avoid unnecessary page table allocation in kvm_tdp_mmu_map() Kai Huang
2021-04-29 16:22 ` Ben Gardon
2021-04-29 17:05   ` Paolo Bonzini

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).