[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Clean up grant-table pinning logic.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxxxxxxxx # Node ID 66dd34f2f439e49e5a19c77ac7e7085a8b18a226 # Parent 4fc1688d9a163644b4c3b15072432d1c2b203c50 [XEN] Clean up grant-table pinning logic. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/common/grant_table.c | 154 +++++++++++++++++++++-------------------------- 1 files changed, 70 insertions(+), 84 deletions(-) diff -r 4fc1688d9a16 -r 66dd34f2f439 xen/common/grant_table.c --- a/xen/common/grant_table.c Tue Sep 05 17:26:20 2006 +0100 +++ b/xen/common/grant_table.c Tue Sep 05 12:20:31 2006 -0700 @@ -90,11 +90,8 @@ __gnttab_map_grant_ref( unsigned long frame = 0; int rc = GNTST_okay; struct active_grant_entry *act; - - /* Entry details from @rd's shared grant table. */ grant_entry_t *sha; - domid_t sdom; - u16 sflags; + union grant_combo scombo, prev_scombo, new_scombo; /* * We bound the number of times we retry CMPXCHG on memory locations that @@ -175,13 +172,20 @@ __gnttab_map_grant_ref( spin_lock(&rd->grant_table->lock); - sdom = sha->domid; + /* If already pinned, check the active domid and avoid refcnt overflow. */ + if ( act->pin && + ((act->domid != ld->domain_id) || + (act->pin & 0x80808080U) != 0) ) + PIN_FAIL(unlock_out, GNTST_general_error, + "Bad domain (%d != %d), or risk of counter overflow %08x\n", + act->domid, ld->domain_id, act->pin); if ( !act->pin || (!(op->flags & GNTMAP_readonly) && !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) ) { - sflags = sha->flags; + scombo.shorts.flags = sha->flags; + scombo.shorts.domid = sha->domid; /* * This loop attempts to set the access (reading/writing) flags @@ -191,33 +195,29 @@ __gnttab_map_grant_ref( */ for ( ; ; ) { - union grant_combo scombo, prev_scombo, new_scombo; - - if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) || - unlikely(sdom != led->domain->domain_id) ) - PIN_FAIL(unlock_out, GNTST_general_error, - "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", - sflags, sdom, led->domain->domain_id); - - /* Merge two 16-bit values into a 32-bit combined update. */ - scombo.shorts.flags = sflags; - scombo.shorts.domid = sdom; - + /* If not already pinned, check the grant domid and type. */ + if ( !act->pin && + (((scombo.shorts.flags & GTF_type_mask) != + GTF_permit_access) || + (scombo.shorts.domid != ld->domain_id)) ) + PIN_FAIL(unlock_out, GNTST_general_error, + "Bad flags (%x) or dom (%d). (expected dom %d)\n", + scombo.shorts.flags, scombo.shorts.domid, + ld->domain_id); + new_scombo = scombo; new_scombo.shorts.flags |= GTF_reading; if ( !(op->flags & GNTMAP_readonly) ) { new_scombo.shorts.flags |= GTF_writing; - if ( unlikely(sflags & GTF_readonly) ) + if ( unlikely(scombo.shorts.flags & GTF_readonly) ) PIN_FAIL(unlock_out, GNTST_general_error, "Attempt to write-pin a r/o grant entry.\n"); } prev_scombo.word = cmpxchg((u32 *)&sha->flags, scombo.word, new_scombo.word); - - /* Did the combined update work (did we see what we expected?). */ if ( likely(prev_scombo.word == scombo.word) ) break; @@ -225,24 +225,15 @@ __gnttab_map_grant_ref( PIN_FAIL(unlock_out, GNTST_general_error, "Shared grant entry is unstable.\n"); - /* Didn't see what we expected. Split out the seen flags & dom. */ - sflags = prev_scombo.shorts.flags; - sdom = prev_scombo.shorts.domid; + scombo = prev_scombo; } if ( !act->pin ) { - act->domid = sdom; + act->domid = scombo.shorts.domid; act->frame = gmfn_to_mfn(rd, sha->frame); } } - else if ( unlikely(sdom != ld->domain_id) ) - PIN_FAIL(unlock_out, GNTST_general_error, - "Bad domain (%d). (NB. expected dom %d)\n", - sdom, ld->domain_id); - else if ( (act->pin & 0x80808080U) != 0 ) - PIN_FAIL(unlock_out, ENOSPC, - "Risk of counter overflow %08x\n", act->pin); if ( op->flags & GNTMAP_device_map ) act->pin += (op->flags & GNTMAP_readonly) ? @@ -550,9 +541,7 @@ gnttab_prepare_for_transfer( { struct grant_table *rgt; struct grant_entry *sha; - domid_t sdom; - u16 sflags; - union grant_combo scombo, prev_scombo, tmp_scombo; + union grant_combo scombo, prev_scombo, new_scombo; int retries = 0; if ( unlikely((rgt = rd->grant_table) == NULL) || @@ -567,29 +556,25 @@ gnttab_prepare_for_transfer( sha = &rgt->shared[ref]; - sflags = sha->flags; - sdom = sha->domid; + scombo.shorts.flags = sha->flags; + scombo.shorts.domid = sha->domid; for ( ; ; ) { - if ( unlikely(sflags != GTF_accept_transfer) || - unlikely(sdom != ld->domain_id) ) + if ( unlikely(scombo.shorts.flags != GTF_accept_transfer) || + unlikely(scombo.shorts.domid != ld->domain_id) ) { DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", - sflags, sdom, ld->domain_id); + scombo.shorts.flags, scombo.shorts.domid, + ld->domain_id); goto fail; } - /* Merge two 16-bit values into a 32-bit combined update. */ - scombo.shorts.flags = sflags; - scombo.shorts.domid = sdom; - - tmp_scombo = scombo; - tmp_scombo.shorts.flags |= GTF_transfer_committed; + new_scombo = scombo; + new_scombo.shorts.flags |= GTF_transfer_committed; + prev_scombo.word = cmpxchg((u32 *)&sha->flags, - scombo.word, tmp_scombo.word); - - /* Did the combined update work (did we see what we expected?). */ + scombo.word, new_scombo.word); if ( likely(prev_scombo.word == scombo.word) ) break; @@ -599,9 +584,7 @@ gnttab_prepare_for_transfer( goto fail; } - /* Didn't see what we expected. Split out the seen flags & dom. */ - sflags = prev_scombo.shorts.flags; - sdom = prev_scombo.shorts.domid; + scombo = prev_scombo; } spin_unlock(&rgt->lock); @@ -739,16 +722,21 @@ __release_grant_for_copy( gnttab_mark_dirty(rd, r_frame); spin_lock(&rd->grant_table->lock); + if ( readonly ) + { act->pin -= GNTPIN_hstr_inc; + } else + { act->pin -= GNTPIN_hstw_inc; - - if ( !(act->pin & GNTPIN_hstw_mask) && !readonly ) - gnttab_clear_flag(_GTF_writing, &sha->flags); + if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) ) + gnttab_clear_flag(_GTF_writing, &sha->flags); + } if ( !act->pin ) gnttab_clear_flag(_GTF_reading, &sha->flags); + spin_unlock(&rd->grant_table->lock); } @@ -764,8 +752,7 @@ __acquire_grant_for_copy( struct active_grant_entry *act; s16 rc = GNTST_okay; int retries = 0; - u16 sflags; - domid_t sdom; + union grant_combo scombo, prev_scombo, new_scombo; if ( unlikely(gref >= NR_GRANT_ENTRIES) ) PIN_FAIL(error_out, GNTST_bad_gntref, @@ -776,37 +763,43 @@ __acquire_grant_for_copy( spin_lock(&rd->grant_table->lock); - sdom = sha->domid; + /* If already pinned, check the active domid and avoid refcnt overflow. */ + if ( act->pin && + ((act->domid != current->domain->domain_id) || + (act->pin & 0x80808080U) != 0) ) + PIN_FAIL(unlock_out, GNTST_general_error, + "Bad domain (%d != %d), or risk of counter overflow %08x\n", + act->domid, current->domain->domain_id, act->pin); if ( !act->pin || - (!readonly && !(act->pin & GNTPIN_hstw_mask)) ) - { - sflags = sha->flags; + (!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) ) + { + scombo.shorts.flags = sha->flags; + scombo.shorts.domid = sha->domid; for ( ; ; ) { - union grant_combo scombo, prev_scombo, new_scombo; - - if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access || - sdom != current->domain->domain_id ) ) - PIN_FAIL(unlock_out, GNTST_general_error, - "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", - sflags, sdom, current->domain->domain_id); - - /* Merge two 16-bit values into a 32-bit combined update. */ - scombo.shorts.flags = sflags; - scombo.shorts.domid = sdom; - + /* If not already pinned, check the grant domid and type. */ + if ( !act->pin && + (((scombo.shorts.flags & GTF_type_mask) != + GTF_permit_access) || + (scombo.shorts.domid != current->domain->domain_id)) ) + PIN_FAIL(unlock_out, GNTST_general_error, + "Bad flags (%x) or dom (%d). (expected dom %d)\n", + scombo.shorts.flags, scombo.shorts.domid, + current->domain->domain_id); + new_scombo = scombo; new_scombo.shorts.flags |= GTF_reading; if ( !readonly ) { new_scombo.shorts.flags |= GTF_writing; - if ( unlikely(sflags & GTF_readonly) ) + if ( unlikely(scombo.shorts.flags & GTF_readonly) ) PIN_FAIL(unlock_out, GNTST_general_error, "Attempt to write-pin a r/o grant entry.\n"); } + prev_scombo.word = cmpxchg((u32 *)&sha->flags, scombo.word, new_scombo.word); if ( likely(prev_scombo.word == scombo.word) ) @@ -815,23 +808,16 @@ __acquire_grant_for_copy( if ( retries++ == 4 ) PIN_FAIL(unlock_out, GNTST_general_error, "Shared grant entry is unstable.\n"); - sflags = prev_scombo.shorts.flags; - sdom = prev_scombo.shorts.flags; + + scombo = prev_scombo; } if ( !act->pin ) { - act->domid = sdom; + act->domid = scombo.shorts.domid; act->frame = gmfn_to_mfn(rd, sha->frame); } } - else if ( unlikely(sdom != current->domain->domain_id) ) - PIN_FAIL(unlock_out, GNTST_general_error, - "Bad domain (%d). (NB. expected dom %d)\n", - sdom, current->domain->domain_id); - else if ( (act->pin & 0x80808080U) != 0 ) - PIN_FAIL(unlock_out, ENOSPC, - "Risk of counter overflow %08x\n", act->pin); act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |