[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-4.1-testing] Fix shared entry status for grant copy operation on paged-out gfn
# HG changeset patch # User Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx> # Date 1348131319 -7200 # Node ID 4210b36bfc416c27ed4d4313003a6278bdfdbb4a # Parent 6162d01a51499009913119334fa6f061b5fea283 Fix shared entry status for grant copy operation on paged-out gfn The unwind path was not clearing the shared entry status bits. This was BSOD-ing guests on network activity under certain configurations. Also: * sed the fixup method name to signal it's related to grant copy. * use atomic clear flag ops during fixup. Signed-off-by: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx> xen-unstable changeset: 25771:1636cc4886f6 xen-unstable date: Wed Aug 22 21:27:50 UTC 2012 --- diff -r 6162d01a5149 -r 4210b36bfc41 xen/common/grant_table.c --- a/xen/common/grant_table.c Thu Sep 20 10:53:43 2012 +0200 +++ b/xen/common/grant_table.c Thu Sep 20 10:55:19 2012 +0200 @@ -1707,14 +1707,14 @@ __release_grant_for_copy( under the domain's grant table lock. */ /* Only safe on transitive grants. Even then, note that we don't attempt to drop any pin on the referent grant. */ -static void __fixup_status_for_pin(const struct active_grant_entry *act, +static void __fixup_status_for_copy_pin(const struct active_grant_entry *act, uint16_t *status) { if ( !(act->pin & GNTPIN_hstw_mask) ) - *status &= ~GTF_writing; + gnttab_clear_flag(_GTF_writing, status); if ( !(act->pin & GNTPIN_hstr_mask) ) - *status &= ~GTF_reading; + gnttab_clear_flag(_GTF_reading, status); } /* Grab a frame number from a grant entry and update the flags and pin @@ -1794,7 +1794,7 @@ __acquire_grant_for_copy( if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive ) { if ( !allow_transitive ) - PIN_FAIL(unlock_out, GNTST_general_error, + PIN_FAIL(unlock_out_clear, GNTST_general_error, "transitive grant when transitivity not allowed\n"); trans_domid = sha2->transitive.trans_domid; @@ -1802,7 +1802,7 @@ __acquire_grant_for_copy( barrier(); /* Stop the compiler from re-loading trans_domid from shared memory */ if ( trans_domid == rd->domain_id ) - PIN_FAIL(unlock_out, GNTST_general_error, + PIN_FAIL(unlock_out_clear, GNTST_general_error, "transitive grants cannot be self-referential\n"); /* We allow the trans_domid == ld->domain_id case, which @@ -1814,7 +1814,7 @@ __acquire_grant_for_copy( rrd = rcu_lock_domain_by_id(trans_domid); if ( rrd == NULL ) - PIN_FAIL(unlock_out, GNTST_general_error, + PIN_FAIL(unlock_out_clear, GNTST_general_error, "transitive grant referenced bad domain %d\n", trans_domid); spin_unlock(&rd->grant_table->lock); @@ -1826,7 +1826,7 @@ __acquire_grant_for_copy( spin_lock(&rd->grant_table->lock); if ( rc != GNTST_okay ) { - __fixup_status_for_pin(act, status); + __fixup_status_for_copy_pin(act, status); spin_unlock(&rd->grant_table->lock); return rc; } @@ -1837,7 +1837,7 @@ __acquire_grant_for_copy( and try again. */ if ( act->pin != old_pin ) { - __fixup_status_for_pin(act, status); + __fixup_status_for_copy_pin(act, status); spin_unlock(&rd->grant_table->lock); return __acquire_grant_for_copy(rd, gref, ld, readonly, frame, page_off, length, @@ -1857,7 +1857,7 @@ __acquire_grant_for_copy( gfn = sha1->frame; rc = __get_paged_frame(gfn, &grant_frame, readonly, rd); if ( rc != GNTST_okay ) - goto unlock_out; + goto unlock_out_clear; act->gfn = gfn; is_sub_page = 0; trans_page_off = 0; @@ -1869,7 +1869,7 @@ __acquire_grant_for_copy( gfn = sha2->full_page.frame; rc = __get_paged_frame(gfn, &grant_frame, readonly, rd); if ( rc != GNTST_okay ) - goto unlock_out; + goto unlock_out_clear; act->gfn = gfn; is_sub_page = 0; trans_page_off = 0; @@ -1881,7 +1881,7 @@ __acquire_grant_for_copy( gfn = sha2->sub_page.frame; rc = __get_paged_frame(gfn, &grant_frame, readonly, rd); if ( rc != GNTST_okay ) - goto unlock_out; + goto unlock_out_clear; act->gfn = gfn; is_sub_page = 1; trans_page_off = sha2->sub_page.page_off; @@ -1911,6 +1911,17 @@ __acquire_grant_for_copy( *length = act->length; *frame = act->frame; + spin_unlock(&rd->grant_table->lock); + return rc; + + unlock_out_clear: + if ( !(readonly) && + !(act->pin & GNTPIN_hstw_mask) ) + gnttab_clear_flag(_GTF_writing, status); + + if ( !act->pin ) + gnttab_clear_flag(_GTF_reading, status); + unlock_out: spin_unlock(&rd->grant_table->lock); return rc; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |