[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix gnttab_release_mappings -- it doesn't need to drop
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID b3edbeea3e797b7e56d13ab7ae126fbcd1fb6a70 # Parent 48eb10d7a2d608351023b14e45a9ddb7f99cab8a Fix gnttab_release_mappings -- it doesn't need to drop page refcnts for host mappings as they are already destroyed by put_page_from_l1e(). Also call gnttab_release_mappings later (after destroying page-table references) and from common code rather than arch/x86. Also a few other misc gnttab cleanups. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Dec 21 17:25:34 2005 +++ b/xen/arch/x86/domain.c Wed Dec 21 17:45:43 2005 @@ -957,8 +957,6 @@ ptwr_destroy(d); - gnttab_release_mappings(d); - /* Drop the in-use references to page-table bases. */ for_each_vcpu ( d, v ) { diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Wed Dec 21 17:25:34 2005 +++ b/xen/arch/x86/setup.c Wed Dec 21 17:45:43 2005 @@ -488,8 +488,6 @@ start_of_day(); - grant_table_init(); - shadow_mode_init(); /* initialize access control security module */ diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/common/domain.c --- a/xen/common/domain.c Wed Dec 21 17:25:34 2005 +++ b/xen/common/domain.c Wed Dec 21 17:45:43 2005 @@ -118,6 +118,7 @@ for_each_vcpu(d, v) sched_rem_domain(v); domain_relinquish_resources(d); + gnttab_release_mappings(d); put_domain(d); send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC); diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/common/grant_table.c --- a/xen/common/grant_table.c Wed Dec 21 17:25:34 2005 +++ b/xen/common/grant_table.c Wed Dec 21 17:45:43 2005 @@ -611,6 +611,91 @@ spin_unlock(>->lock); put_domain(d); + return 0; +} + +/* + * Check that the given grant reference (rd,ref) allows 'ld' to transfer + * ownership of a page frame. If so, lock down the grant entry. + */ +static int +gnttab_prepare_for_transfer( + struct domain *rd, struct domain *ld, grant_ref_t ref) +{ + grant_table_t *rgt; + grant_entry_t *sha; + domid_t sdom; + u16 sflags; + u32 scombo, prev_scombo; + int retries = 0; + unsigned long target_pfn; + + if ( unlikely((rgt = rd->grant_table) == NULL) || + unlikely(ref >= NR_GRANT_ENTRIES) ) + { + DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n", + rd->domain_id, ref); + return 0; + } + + spin_lock(&rgt->lock); + + sha = &rgt->shared[ref]; + + sflags = sha->flags; + sdom = sha->domid; + + for ( ; ; ) + { + target_pfn = sha->frame; + + if ( unlikely(target_pfn >= max_page ) ) + { + DPRINTK("Bad pfn (%lx)\n", target_pfn); + goto fail; + } + + if ( unlikely(sflags != GTF_accept_transfer) || + unlikely(sdom != ld->domain_id) ) + { + DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", + sflags, sdom, ld->domain_id); + goto fail; + } + + /* Merge two 16-bit values into a 32-bit combined update. */ + /* NB. Endianness! */ + prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags; + + /* NB. prev_scombo is updated in place to seen value. */ + if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, + prev_scombo | GTF_transfer_committed)) ) + { + DPRINTK("Fault while modifying shared flags and domid.\n"); + goto fail; + } + + /* Did the combined update work (did we see what we expected?). */ + if ( likely(prev_scombo == scombo) ) + break; + + if ( retries++ == 4 ) + { + DPRINTK("Shared grant entry is unstable.\n"); + goto fail; + } + + /* Didn't see what we expected. Split out the seen flags & dom. */ + /* NB. Endianness! */ + sflags = (u16)prev_scombo; + sdom = (u16)(prev_scombo >> 16); + } + + spin_unlock(&rgt->lock); + return 1; + + fail: + spin_unlock(&rgt->lock); return 0; } @@ -763,87 +848,6 @@ } int -gnttab_prepare_for_transfer( - struct domain *rd, struct domain *ld, grant_ref_t ref) -{ - grant_table_t *rgt; - grant_entry_t *sha; - domid_t sdom; - u16 sflags; - u32 scombo, prev_scombo; - int retries = 0; - unsigned long target_pfn; - - if ( unlikely((rgt = rd->grant_table) == NULL) || - unlikely(ref >= NR_GRANT_ENTRIES) ) - { - DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n", - rd->domain_id, ref); - return 0; - } - - spin_lock(&rgt->lock); - - sha = &rgt->shared[ref]; - - sflags = sha->flags; - sdom = sha->domid; - - for ( ; ; ) - { - target_pfn = sha->frame; - - if ( unlikely(target_pfn >= max_page ) ) - { - DPRINTK("Bad pfn (%lx)\n", target_pfn); - goto fail; - } - - if ( unlikely(sflags != GTF_accept_transfer) || - unlikely(sdom != ld->domain_id) ) - { - DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", - sflags, sdom, ld->domain_id); - goto fail; - } - - /* Merge two 16-bit values into a 32-bit combined update. */ - /* NB. Endianness! */ - prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags; - - /* NB. prev_scombo is updated in place to seen value. */ - if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, - prev_scombo | GTF_transfer_committed)) ) - { - DPRINTK("Fault while modifying shared flags and domid.\n"); - goto fail; - } - - /* Did the combined update work (did we see what we expected?). */ - if ( likely(prev_scombo == scombo) ) - break; - - if ( retries++ == 4 ) - { - DPRINTK("Shared grant entry is unstable.\n"); - goto fail; - } - - /* Didn't see what we expected. Split out the seen flags & dom. */ - /* NB. Endianness! */ - sflags = (u16)prev_scombo; - sdom = (u16)(prev_scombo >> 16); - } - - spin_unlock(&rgt->lock); - return 1; - - fail: - spin_unlock(&rgt->lock); - return 0; -} - -int grant_table_create( struct domain *d) { @@ -943,7 +947,8 @@ { BUG_ON(!(act->pin & GNTPIN_hstr_mask)); act->pin -= GNTPIN_hstr_inc; - put_page(pfn_to_page(act->frame)); + /* Done implicitly when page tables are destroyed. */ + /* put_page(pfn_to_page(act->frame)); */ } } else @@ -959,7 +964,8 @@ { BUG_ON(!(act->pin & GNTPIN_hstw_mask)); act->pin -= GNTPIN_hstw_inc; - put_page_and_type(pfn_to_page(act->frame)); + /* Done implicitly when page tables are destroyed. */ + /* put_page_and_type(pfn_to_page(act->frame)); */ } if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 ) @@ -982,24 +988,17 @@ grant_table_destroy( struct domain *d) { - grant_table_t *t; - - if ( (t = d->grant_table) != NULL ) - { - /* Free memory relating to this grant table. */ - d->grant_table = NULL; - free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES); - free_xenheap_page(t->maptrack); - xfree(t->active); - xfree(t); - } -} - -void -grant_table_init( - void) -{ - /* Nothing. */ + grant_table_t *t = d->grant_table; + + if ( t == NULL ) + return; + + free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES); + free_xenheap_page(t->maptrack); + xfree(t->active); + xfree(t); + + d->grant_table = NULL; } /* diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/include/xen/grant_table.h --- a/xen/include/xen/grant_table.h Wed Dec 21 17:25:34 2005 +++ b/xen/include/xen/grant_table.h Wed Dec 21 17:45:43 2005 @@ -84,23 +84,11 @@ spinlock_t lock; } grant_table_t; -/* Start-of-day system initialisation. */ -void grant_table_init( - void); - /* Create/destroy per-domain grant table context. */ int grant_table_create( struct domain *d); void grant_table_destroy( struct domain *d); - -/* - * Check that the given grant reference (rd,ref) allows 'ld' to transfer - * ownership of a page frame. If so, lock down the grant entry. - */ -int -gnttab_prepare_for_transfer( - struct domain *rd, struct domain *ld, grant_ref_t ref); /* Domain death release of granted mappings of other domains' memory. */ void _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |