From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757523AbcBSLzS (ORCPT ); Fri, 19 Feb 2016 06:55:18 -0500 Received: from mail-wm0-f43.google.com ([74.125.82.43]:38670 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757093AbcBSLzO (ORCPT ); Fri, 19 Feb 2016 06:55:14 -0500 Subject: Re: [PATCH v3 10/11] KVM: MMU: clear write-flooding on the fast path of tracked page To: Xiao Guangrong References: <1455449503-20993-1-git-send-email-guangrong.xiao@linux.intel.com> <1455449503-20993-11-git-send-email-guangrong.xiao@linux.intel.com> Cc: gleb@kernel.org, mtosatti@redhat.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kai.huang@linux.intel.com, jike.song@intel.com From: Paolo Bonzini Message-ID: <56C7029F.8010106@redhat.com> Date: Fri, 19 Feb 2016 12:55:11 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 MIME-Version: 1.0 In-Reply-To: <1455449503-20993-11-git-send-email-guangrong.xiao@linux.intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 > --- > 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; > >