qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Zhuangyanying <ann.zhuangyanying@huawei.com>
Cc: xiaoguangrong@tencent.com, pbonzini@redhat.com,
	arei.gonglei@huawei.com, qemu-devel@nongnu.org,
	kvm@vger.kernel.org, wangxinxin.wang@huawei.com,
	liu.jinsong@huawei.com
Subject: Re: [Qemu-devel] [PATCH 2/4] KVM: MMU: introduce possible_writable_spte_bitmap
Date: Thu, 17 Jan 2019 07:55:42 -0800	[thread overview]
Message-ID: <20190117155542.GB22169@linux.intel.com> (raw)
In-Reply-To: <1547733331-16140-3-git-send-email-ann.zhuangyanying@huawei.com>

On Thu, Jan 17, 2019 at 01:55:29PM +0000, Zhuangyanying wrote:
> From: Xiao Guangrong <xiaoguangrong@tencent.com>
> 
> It is used to track possible writable sptes on the shadow page on
> which the bit is set to 1 for the sptes that are already writable
> or can be locklessly updated to writable on the fast_page_fault
> path, also a counter for the number of possible writable sptes is
> introduced to speed up bitmap walking
> 
> Later patch will benefit good performance by using this bitmap and
> counter to fast figure out writable sptes and write protect them
> 
> Signed-off-by: Xiao Guangrong <xiaoguangrong@tencent.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  6 ++++-
>  arch/x86/kvm/mmu.c              | 53 ++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 4660ce9..5c30aa0 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -128,6 +128,7 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
>  #define KVM_MIN_ALLOC_MMU_PAGES 64
>  #define KVM_MMU_HASH_SHIFT 12
>  #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT)
> +#define KVM_MMU_SP_ENTRY_NR 512
>  #define KVM_MIN_FREE_MMU_PAGES 5
>  #define KVM_REFILL_PAGES 25
>  #define KVM_MAX_CPUID_ENTRIES 80
> @@ -331,12 +332,15 @@ struct kvm_mmu_page {
>  	gfn_t *gfns;
>  	int root_count;          /* Currently serving as active root */
>  	unsigned int unsync_children;
> +	unsigned int possiable_writable_sptes;

s/possiable/possible

>  	struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
>  
>  	/* The page is obsolete if mmu_valid_gen != kvm->arch.mmu_valid_gen.  */
>  	unsigned long mmu_valid_gen;
>  
> -	DECLARE_BITMAP(unsync_child_bitmap, 512);
> +	DECLARE_BITMAP(unsync_child_bitmap, KVM_MMU_SP_ENTRY_NR);
> +
> +	DECLARE_BITMAP(possible_writable_spte_bitmap, KVM_MMU_SP_ENTRY_NR);
>  
>  #ifdef CONFIG_X86_32
>  	/*
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index eeb3bac..9daab00 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -718,6 +718,49 @@ static bool is_dirty_spte(u64 spte)
>  	return dirty_mask ? spte & dirty_mask : spte & PT_WRITABLE_MASK;
>  }
>  
> +static bool is_possible_writable_spte(u64 spte)
> +{
> +	if (!is_shadow_present_pte(spte))
> +		return false;
> +
> +	if (is_writable_pte(spte))
> +		return true;
> +
> +	if (spte_can_locklessly_be_made_writable(spte))
> +		return true;
> +
> +	/*
> +	 * although is_access_track_spte() sptes can be updated out of
> +	 * mmu-lock, we need not take them into account as access_track
> +	 * drops writable bit for them
> +	 */
> +	return false;
> +}
> +
> +static void
> +mmu_log_possible_writable_spte(u64 *sptep, u64 old_spte, u64 new_spte)
> +{
> +	struct kvm_mmu_page *sp = page_header(__pa(sptep));
> +	bool old_state, new_state;
> +
> +	old_state = is_possible_writable_spte(old_spte);
> +	new_state = is_possible_writable_spte(new_spte);
> +
> +	if (old_state == new_state)
> +		return;
> +
> +	/* a possible writable spte is dropped */
> +	if (old_state) {
> +		sp->possiable_writable_sptes--;
> +		__clear_bit(sptep - sp->spt, sp->possible_writable_spte_bitmap);
> +		return;
> +	}
> +
> +	/* a new possible writable spte is set */
> +	sp->possiable_writable_sptes++;
> +	__set_bit(sptep - sp->spt, sp->possible_writable_spte_bitmap);
> +}
> +
>  /* Rules for using mmu_spte_set:
>   * Set the sptep from nonpresent to present.
>   * Note: the sptep being assigned *must* be either not present
> @@ -728,6 +771,7 @@ static void mmu_spte_set(u64 *sptep, u64 new_spte)
>  {
>  	WARN_ON(is_shadow_present_pte(*sptep));
>  	__set_spte(sptep, new_spte);
> +	mmu_log_possible_writable_spte(sptep, 0ull, new_spte);
>  }
>  
>  /*
> @@ -746,6 +790,7 @@ static void mmu_spte_update_no_track(u64 *sptep, u64 new_spte)
>  	}
>  
>  	__update_clear_spte_fast(sptep, new_spte);
> +	mmu_log_possible_writable_spte(sptep, old_spte, new_spte);

Hmm, maybe it's just me, but I find the "track vs. no_track" terminology
quite confusing, e.g. the "no_track" functions are now logging sptes.
Track and log aren't exact synonyms, but they're pretty closed.

>  }
>  
>  /*
> @@ -771,6 +816,7 @@ static u64 mmu_spte_update_track(u64 *sptep, u64 new_spte)
>  
>  	WARN_ON(spte_to_pfn(old_spte) != spte_to_pfn(new_spte));
>  
> +	mmu_log_possible_writable_spte(sptep, old_spte, new_spte);
>  	return old_spte;
>  }
>  
> @@ -836,6 +882,8 @@ static int mmu_spte_clear_track_bits(u64 *sptep)
>  	else
>  		old_spte = __update_clear_spte_slow(sptep, 0ull);
>  
> +	mmu_log_possible_writable_spte(sptep, old_spte, 0ull);
> +
>  	if (!is_shadow_present_pte(old_spte))
>  		return 0;
>  
> @@ -864,7 +912,10 @@ static int mmu_spte_clear_track_bits(u64 *sptep)
>   */
>  static void mmu_spte_clear_no_track(u64 *sptep)
>  {
> +	u64 old_spte = *sptep;
> +
>  	__update_clear_spte_fast(sptep, 0ull);
> +	mmu_log_possible_writable_spte(sptep, old_spte, 0ull);
>  }
>  
>  static u64 mmu_spte_get_lockless(u64 *sptep)
> @@ -2159,7 +2210,7 @@ static int __mmu_unsync_walk(struct kvm_mmu_page *sp,
>  {
>  	int i, ret, nr_unsync_leaf = 0;
>  
> -	for_each_set_bit(i, sp->unsync_child_bitmap, 512) {
> +	for_each_set_bit(i, sp->unsync_child_bitmap, KVM_MMU_SP_ENTRY_NR) {
>  		struct kvm_mmu_page *child;
>  		u64 ent = sp->spt[i];
>  
> -- 
> 1.8.3.1
> 
> 

  reply	other threads:[~2019-01-17 15:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-17 13:55 [Qemu-devel] [PATCH 0/4] KVM: MMU: fast cleanup D bit based on fast write protect Zhuangyanying
2019-01-17 13:55 ` [Qemu-devel] [PATCH 1/4] KVM: MMU: correct the behavior of mmu_spte_update_no_track Zhuangyanying
2019-01-17 15:44   ` Sean Christopherson
2019-01-17 13:55 ` [Qemu-devel] [PATCH 2/4] KVM: MMU: introduce possible_writable_spte_bitmap Zhuangyanying
2019-01-17 15:55   ` Sean Christopherson [this message]
2019-01-17 13:55 ` [Qemu-devel] [PATCH 3/4] KVM: MMU: introduce kvm_mmu_write_protect_all_pages Zhuangyanying
2019-01-17 16:09   ` Sean Christopherson
2019-01-17 13:55 ` [Qemu-devel] [PATCH 4/4] KVM: MMU: fast cleanup D bit based on fast write protect Zhuangyanying
2019-01-17 16:32   ` Sean Christopherson
2019-01-21  6:37     ` Zhuangyanying
2019-01-22 15:17       ` Sean Christopherson
2019-01-23 18:38         ` Zhuangyanying

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=20190117155542.GB22169@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=ann.zhuangyanying@huawei.com \
    --cc=arei.gonglei@huawei.com \
    --cc=kvm@vger.kernel.org \
    --cc=liu.jinsong@huawei.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=wangxinxin.wang@huawei.com \
    --cc=xiaoguangrong@tencent.com \
    /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).