diff options
author | Ian Jackson <Ian.Jackson@eu.citrix.com> | 2012-10-26 16:49:18 +0100 |
---|---|---|
committer | Ian Jackson <Ian.Jackson@eu.citrix.com> | 2012-10-26 16:49:18 +0100 |
commit | c0167fb3ca523717a7da3e4a312478c3d8a80a56 (patch) | |
tree | 420f24415f6d4cdac128644692f7597138ae62b1 | |
parent | c3f3a3c092315e3eeee0b2cb0ba3e2ce02a3a2dc (diff) | |
download | xen-c0167fb3ca523717a7da3e4a312478c3d8a80a56.tar.gz xen-c0167fb3ca523717a7da3e4a312478c3d8a80a56.tar.bz2 xen-c0167fb3ca523717a7da3e4a312478c3d8a80a56.zip |
libxl: ao: cope with fast ao completion with progess events
There are two egcs in an ao initiator: the one in the AO_CREATE
function, and the one in libxl__ao_inprogress. If synchronous ao
operation generates progress events and completes immediately, the
progress callbacks end up queued in the outer egc. These callbacks
are currently only called after libxl__ao_inprogress has returned, and
keep the ao alive until they happen. This is not good because the
principle is that a synchronous ao is not supposed to survive beyond
libxl__ao_inprogress's return.
The fix is to ensure that the callbacks queued in the outer egc are
called early enough that they don't preserve the ao. This is
straightforward in the AO_INPROGRESS macro because AO_CREATE's egc is
not used inside that macro other than to destroy it. All we have to
do is destroy it a bit sooner.
This involves unlocking and relocking the ctx since EGC_FREE expects
to be called with the lock released but libxl__ao_inprogress needs it
locked. This hole in our lock tenure is fine - libxl__ao_inprogress
has such holes already.
It is still possible to use the CTX_LOCK macros for this unlock/lock
because the gc we are using is destroyed only afterwards by
libxl__ao_inprogress.
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
xen-unstable changeset: 26080:25b2f53d2583
Backport-requested-by: Ian Campbell <Ian.Campbell@citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
-rw-r--r-- | tools/libxl/libxl_internal.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index b6f54bad17..5e5a131e67 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1678,10 +1678,12 @@ _hidden void libxl__egc_cleanup(libxl__egc *egc); #define AO_INPROGRESS ({ \ libxl_ctx *ao__ctx = libxl__gc_owner(&ao->gc); \ + CTX_UNLOCK; \ + EGC_FREE; \ + CTX_LOCK; \ int ao__rc = libxl__ao_inprogress(ao, \ __FILE__, __LINE__, __func__); \ libxl__ctx_unlock(ao__ctx); /* gc is now invalid */ \ - EGC_FREE; \ (ao__rc); \ }) |