Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1333485 > unrolled thread

[PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page

Started byXiao Guangrong <guangrong.xiao@linux.intel.com>
First post2016-02-14 12:50 +0100
Last post2016-02-19 13:00 +0100
Articles 2 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page Xiao Guangrong <guangrong.xiao@linux.intel.com> - 2016-02-14 12:50 +0100
    Re: [PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path  of tracked page Paolo Bonzini <pbonzini@redhat.com> - 2016-02-19 13:00 +0100

#1333485 — [PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page

FromXiao Guangrong <guangrong.xiao@linux.intel.com>
Date2016-02-14 12:50 +0100
Subject[PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page
Message-ID<r23lD-25X-1@gated-at.bofh.it>
If the page fault is caused by write access on write tracked page, the
real shadow page walking is skipped, we lost the chance to clear write
flooding for the page structure current vcpu is using

Fix it by locklessly waking shadow page table to clear write flooding
on the shadow page structure out of mmu-lock. So that we change the
count to atomic_t

Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
---
 arch/x86/include/asm/kvm_host.h |  2 +-
 arch/x86/kvm/mmu.c              | 22 ++++++++++++++++++++--
 arch/x86/kvm/paging_tmpl.h      |  4 +++-
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 282bc2f..254d103 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -277,7 +277,7 @@ struct kvm_mmu_page {
 #endif
 
 	/* Number of writes since the last time traversal visited this page.  */
-	int write_flooding_count;
+	atomic_t write_flooding_count;
 };
 
 struct kvm_pio_request {
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 4986615..f924e6c 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2073,7 +2073,7 @@ static void mmu_sync_children(struct kvm_vcpu *vcpu,
 
 static void __clear_sp_write_flooding_count(struct kvm_mmu_page *sp)
 {
-	sp->write_flooding_count = 0;
+	atomic_set(&sp->write_flooding_count,  0);
 }
 
 static void clear_sp_write_flooding_count(u64 *spte)
@@ -3407,6 +3407,23 @@ static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
 	return false;
 }
 
+static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr)
+{
+	struct kvm_shadow_walk_iterator iterator;
+	u64 spte;
+
+	if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+		return;
+
+	walk_shadow_page_lockless_begin(vcpu);
+	for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
+		clear_sp_write_flooding_count(iterator.sptep);
+		if (!is_shadow_present_pte(spte))
+			break;
+	}
+	walk_shadow_page_lockless_end(vcpu);
+}
+
 static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				u32 error_code, bool prefault)
 {
@@ -4236,7 +4253,8 @@ static bool detect_write_flooding(struct kvm_mmu_page *sp)
 	if (sp->role.level == PT_PAGE_TABLE_LEVEL)
 		return false;
 
-	return ++sp->write_flooding_count >= 3;
+	atomic_inc(&sp->write_flooding_count);
+	return atomic_read(&sp->write_flooding_count) >= 3;
 }
 
 /*
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index c3a30c2..5985156 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -735,8 +735,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
 		return 0;
 	}
 
-	if (page_fault_handle_page_track(vcpu, error_code, walker.gfn))
+	if (page_fault_handle_page_track(vcpu, error_code, walker.gfn)) {
+		shadow_page_table_clear_flood(vcpu, addr);
 		return 1;
+	}
 
 	vcpu->arch.write_fault_to_shadow_pgtable = false;
 
-- 
1.8.3.1

[toc] | [next] | [standalone]


#1338106 — Re: [PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page

FromPaolo Bonzini <pbonzini@redhat.com>
Date2016-02-19 13:00 +0100
SubjectRe: [PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page
Message-ID<r3RT5-4A8-43@gated-at.bofh.it>
In reply to#1333485

On 14/02/2016 12:31, Xiao Guangrong wrote:
> If the page fault is caused by write access on write tracked page, the
> real shadow page walking is skipped, we lost the chance to clear write
> flooding for the page structure current vcpu is using
> 
> Fix it by locklessly waking shadow page table to clear write flooding
> on the shadow page structure out of mmu-lock. So that we change the
> count to atomic_t

Should this be moved earlier in the series, so that the issue never
surfaces?

Paolo

> Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  2 +-
>  arch/x86/kvm/mmu.c              | 22 ++++++++++++++++++++--
>  arch/x86/kvm/paging_tmpl.h      |  4 +++-
>  3 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 282bc2f..254d103 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -277,7 +277,7 @@ struct kvm_mmu_page {
>  #endif
>  
>  	/* Number of writes since the last time traversal visited this page.  */
> -	int write_flooding_count;
> +	atomic_t write_flooding_count;
>  };
>  
>  struct kvm_pio_request {
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index 4986615..f924e6c 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -2073,7 +2073,7 @@ static void mmu_sync_children(struct kvm_vcpu *vcpu,
>  
>  static void __clear_sp_write_flooding_count(struct kvm_mmu_page *sp)
>  {
> -	sp->write_flooding_count = 0;
> +	atomic_set(&sp->write_flooding_count,  0);
>  }
>  
>  static void clear_sp_write_flooding_count(u64 *spte)
> @@ -3407,6 +3407,23 @@ static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
>  	return false;
>  }
>  
> +static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr)
> +{
> +	struct kvm_shadow_walk_iterator iterator;
> +	u64 spte;
> +
> +	if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
> +		return;
> +
> +	walk_shadow_page_lockless_begin(vcpu);
> +	for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
> +		clear_sp_write_flooding_count(iterator.sptep);
> +		if (!is_shadow_present_pte(spte))
> +			break;
> +	}
> +	walk_shadow_page_lockless_end(vcpu);
> +}
> +
>  static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
>  				u32 error_code, bool prefault)
>  {
> @@ -4236,7 +4253,8 @@ static bool detect_write_flooding(struct kvm_mmu_page *sp)
>  	if (sp->role.level == PT_PAGE_TABLE_LEVEL)
>  		return false;
>  
> -	return ++sp->write_flooding_count >= 3;
> +	atomic_inc(&sp->write_flooding_count);
> +	return atomic_read(&sp->write_flooding_count) >= 3;
>  }
>  
>  /*
> diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
> index c3a30c2..5985156 100644
> --- a/arch/x86/kvm/paging_tmpl.h
> +++ b/arch/x86/kvm/paging_tmpl.h
> @@ -735,8 +735,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
>  		return 0;
>  	}
>  
> -	if (page_fault_handle_page_track(vcpu, error_code, walker.gfn))
> +	if (page_fault_handle_page_track(vcpu, error_code, walker.gfn)) {
> +		shadow_page_table_clear_flood(vcpu, addr);
>  		return 1;
> +	}
>  
>  	vcpu->arch.write_fault_to_shadow_pgtable = false;
>  
> 

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web