[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 1/2] x86/shadow: defer/avoid paging_mfn_is_dirty() invocation
On 01/12/2021 10:35, Jan Beulich wrote: > paging_mfn_is_dirty() is moderately expensive, so avoid its use unless > its result might actually change anything. This means moving the > surrounding if() down below all other checks that can result in clearing > _PAGE_RW from sflags, in order to then check whether _PAGE_RW is > actually still set there before calling the function. > > While moving the block of code, fold two if()s and make a few style > adjustments. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > TBD: Perhaps the dirty-VRAM piece also wants moving down a little, such > that all three "level == 1" conditionals can be folded? TBH, lots of the layout looks dubious, but I'm not sure how worthwhile micro-optimising it is. This particular rearrangement is surely unmeasurable. Fixing the (mis)use of mfn_valid() in the logdirty infrastructure will gain a far larger improvement, because that's dropping a fair number of lfence's from multiple paths, but it's still the case that anything here is rare-to-non-existent in production workloads, and vastly dominated by the VMExit cost even when migrating shadow VMs. > > --- a/xen/arch/x86/mm/shadow/multi.c > +++ b/xen/arch/x86/mm/shadow/multi.c > @@ -604,23 +604,6 @@ _sh_propagate(struct vcpu *v, > && !(gflags & _PAGE_DIRTY)) ) > sflags &= ~_PAGE_RW; > > - // shadow_mode_log_dirty support > - // > - // Only allow the guest write access to a page a) on a demand fault, > - // or b) if the page is already marked as dirty. > - // > - // (We handle log-dirty entirely inside the shadow code, without using > the > - // p2m_ram_logdirty p2m type: only HAP uses that.) > - if ( unlikely((level == 1) && shadow_mode_log_dirty(d)) ) > - { > - if ( mfn_valid(target_mfn) ) { > - if ( ft & FETCH_TYPE_WRITE ) > - paging_mark_dirty(d, target_mfn); > - else if ( !paging_mfn_is_dirty(d, target_mfn) ) > - sflags &= ~_PAGE_RW; > - } > - } > - > #ifdef CONFIG_HVM > if ( unlikely(level == 1) && is_hvm_domain(d) ) > { > @@ -661,6 +644,25 @@ _sh_propagate(struct vcpu *v, > ) ) > sflags &= ~_PAGE_RW; > > + /* > + * shadow_mode_log_dirty support > + * > + * Only allow the guest write access to a page a) on a demand fault, > + * or b) if the page is already marked as dirty. > + * > + * (We handle log-dirty entirely inside the shadow code, without using > the > + * p2m_ram_logdirty p2m type: only HAP uses that.) > + */ > + if ( level == 1 && unlikely(shadow_mode_log_dirty(d)) && > + mfn_valid(target_mfn) ) > + { > + if ( ft & FETCH_TYPE_WRITE ) > + paging_mark_dirty(d, target_mfn); > + else if ( (sflags & _PAGE_RW) && > + !paging_mfn_is_dirty(d, target_mfn) ) > + sflags &= ~_PAGE_RW; This is almost crying out for a logdirty_test_and_maybe_set() helper, because the decent of the logdirty trie is common between the two, but as this would be the only user, probably not worth it. However, the more I look at the logdirty logic, the more it is clear that all the mfn_valid() tests should change to MFN_INVALID, and the result will be far more efficient. ~Andrew > + } > + > // PV guests in 64-bit mode use two different page tables for user vs > // supervisor permissions, making the guest's _PAGE_USER bit irrelevant. > // It is always shadowed as present... > >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |