[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [shadow] Be smarter about what we check to avoid unnecessary brute-force searches
# HG changeset patch # User George Dunlap <gdunlap@xxxxxxxxxxxxx> # Date 1190199484 -3600 # Node ID 91a5b7eaede33414a6bade9ef50c9b2d1ffa4686 # Parent fadd1f8222b3fc3e41977863825871dbc8514344 [shadow] Be smarter about what we check to avoid unnecessary brute-force searches The old code checked only if the page was still a pagetable before doing a brute-force search, rather than checking if it was still shadowed as the type indicated. This meant that if a page was shadowed as two different types, it was guaranteed to do a full brute-force search even if all references could be found by up-pointers. This checks the proper thing so that it will only do a brute-force if necessary. It also re-orders the unshadows so that higher levels are done first. In many cases, lower-level shadows will be destroyed in the process of higher-level shadows being destroyed, again saving brute-force searches. --- xen/arch/x86/mm/shadow/common.c | 59 +++++++++++++++++++++------------------- 1 files changed, 31 insertions(+), 28 deletions(-) diff -r fadd1f8222b3 -r 91a5b7eaede3 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Wed Sep 19 11:42:05 2007 +0100 +++ b/xen/arch/x86/mm/shadow/common.c Wed Sep 19 11:58:04 2007 +0100 @@ -1981,7 +1981,6 @@ void sh_remove_shadows(struct vcpu *v, m { struct page_info *pg = mfn_to_page(gmfn); mfn_t smfn; - u32 sh_flags; int do_locking; unsigned char t; @@ -2065,42 +2064,46 @@ void sh_remove_shadows(struct vcpu *v, m /* Search for this shadow in all appropriate shadows */ perfc_incr(shadow_unshadow); - sh_flags = pg->shadow_flags; /* Lower-level shadows need to be excised from upper-level shadows. * This call to hash_foreach() looks dangerous but is in fact OK: each * call will remove at most one shadow, and terminate immediately when * it does remove it, so we never walk the hash after doing a deletion. */ -#define DO_UNSHADOW(_type) do { \ - t = (_type); \ - smfn = shadow_hash_lookup(v, mfn_x(gmfn), t); \ - if ( unlikely(!mfn_valid(smfn)) ) \ - { \ - SHADOW_ERROR(": gmfn %#lx has flags 0x%"PRIx32 \ - " but no type-0x%"PRIx32" shadow\n", \ - mfn_x(gmfn), sh_flags, t); \ - break; \ - } \ - if ( sh_type_is_pinnable(v, t) ) \ - sh_unpin(v, smfn); \ - else \ - sh_remove_shadow_via_pointer(v, smfn); \ - if ( (pg->count_info & PGC_page_table) && !fast ) \ - hash_foreach(v, masks[t], callbacks, smfn); \ +#define DO_UNSHADOW(_type) do { \ + t = (_type); \ + if( !(pg->count_info & PGC_page_table) \ + || !(pg->shadow_flags & (1 << t)) ) \ + break; \ + smfn = shadow_hash_lookup(v, mfn_x(gmfn), t); \ + if ( unlikely(!mfn_valid(smfn)) ) \ + { \ + SHADOW_ERROR(": gmfn %#lx has flags 0x%"PRIx32 \ + " but no type-0x%"PRIx32" shadow\n", \ + mfn_x(gmfn), (uint32_t)pg->shadow_flags, t); \ + break; \ + } \ + if ( sh_type_is_pinnable(v, t) ) \ + sh_unpin(v, smfn); \ + else \ + sh_remove_shadow_via_pointer(v, smfn); \ + if( !fast \ + && (pg->count_info & PGC_page_table) \ + && (pg->shadow_flags & (1 << t)) ) \ + hash_foreach(v, masks[t], callbacks, smfn); \ } while (0) - if ( sh_flags & SHF_L1_32 ) DO_UNSHADOW(SH_type_l1_32_shadow); - if ( sh_flags & SHF_L2_32 ) DO_UNSHADOW(SH_type_l2_32_shadow); + DO_UNSHADOW(SH_type_l2_32_shadow); + DO_UNSHADOW(SH_type_l1_32_shadow); #if CONFIG_PAGING_LEVELS >= 3 - if ( sh_flags & SHF_L1_PAE ) DO_UNSHADOW(SH_type_l1_pae_shadow); - if ( sh_flags & SHF_L2_PAE ) DO_UNSHADOW(SH_type_l2_pae_shadow); - if ( sh_flags & SHF_L2H_PAE ) DO_UNSHADOW(SH_type_l2h_pae_shadow); + DO_UNSHADOW(SH_type_l2h_pae_shadow); + DO_UNSHADOW(SH_type_l2_pae_shadow); + DO_UNSHADOW(SH_type_l1_pae_shadow); #if CONFIG_PAGING_LEVELS >= 4 - if ( sh_flags & SHF_L1_64 ) DO_UNSHADOW(SH_type_l1_64_shadow); - if ( sh_flags & SHF_L2_64 ) DO_UNSHADOW(SH_type_l2_64_shadow); - if ( sh_flags & SHF_L2H_64 ) DO_UNSHADOW(SH_type_l2h_64_shadow); - if ( sh_flags & SHF_L3_64 ) DO_UNSHADOW(SH_type_l3_64_shadow); - if ( sh_flags & SHF_L4_64 ) DO_UNSHADOW(SH_type_l4_64_shadow); + DO_UNSHADOW(SH_type_l4_64_shadow); + DO_UNSHADOW(SH_type_l3_64_shadow); + DO_UNSHADOW(SH_type_l2h_64_shadow); + DO_UNSHADOW(SH_type_l2_64_shadow); + DO_UNSHADOW(SH_type_l1_64_shadow); #endif #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |