mirror of https://github.com/xemu-project/xemu.git
-----BEGIN PGP SIGNATURE-----
iQEcBAABAgAGBQJX7Ai6AAoJEJykq7OBq3PIR0wIAJ+ZobOxcZ0un8Gx+YY1iPxK aq7VQiin8fE6/RQFCmK2JosTZxqrOUgVFnYCeJsNYgcWQIGFYm4LXYYM3ElYRH2W GSbH/PlpwJ/pb1k48AJ/XBBTcjDv9tyRasY25kcOecubyAMNmIX4uHx3kTab2093 kEdPbKuOJk0r4fzuaTqrDSTa1tJzh8dqvkh2l2OxK2tO+nHlELzG3qAHfl8S1qPw StJ+hYf67jiwHOb8+JHmK6Joj7k3txQ2DyQvPbkVL4xCKWTxrKMPayZD3Lag2msB zmC6kVBPhcIe7iPc/NXaXDUaUcPYytehsgHqb+F/DoPPRhRtWThdeDtQG+BU5sg= =poSl -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging # gpg: Signature made Wed 28 Sep 2016 19:15:22 BST # gpg: using RSA key 0x9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/block-pull-request: linux-aio: fix re-entrant completion processing test-coroutine: test qemu_coroutine_entered() coroutine: add qemu_coroutine_entered() function libqos: fix qvring_init() iothread: check iothread->ctx before aio_context_unref to avoid assertion aio-posix: avoid unnecessary aio_epoll_enabled() calls block: mirror: fix wrong comment of mirror_start Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
bc63afaf5f
12
aio-posix.c
12
aio-posix.c
|
@ -431,11 +431,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||||
assert(npfd == 0);
|
assert(npfd == 0);
|
||||||
|
|
||||||
/* fill pollfds */
|
/* fill pollfds */
|
||||||
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
|
|
||||||
if (!node->deleted && node->pfd.events
|
if (!aio_epoll_enabled(ctx)) {
|
||||||
&& !aio_epoll_enabled(ctx)
|
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
|
||||||
&& aio_node_check(ctx, node->is_external)) {
|
if (!node->deleted && node->pfd.events
|
||||||
add_pollfd(node);
|
&& aio_node_check(ctx, node->is_external)) {
|
||||||
|
add_pollfd(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,9 +94,12 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
||||||
|
|
||||||
laiocb->ret = ret;
|
laiocb->ret = ret;
|
||||||
if (laiocb->co) {
|
if (laiocb->co) {
|
||||||
/* Jump and continue completion for foreign requests, don't do
|
/* If the coroutine is already entered it must be in ioq_submit() and
|
||||||
* anything for current request, it will be completed shortly. */
|
* will notice laio->ret has been filled in when it eventually runs
|
||||||
if (laiocb->co != qemu_coroutine_self()) {
|
* later. Coroutines cannot be entered recursively so avoid doing
|
||||||
|
* that!
|
||||||
|
*/
|
||||||
|
if (!qemu_coroutine_entered(laiocb->co)) {
|
||||||
qemu_coroutine_enter(laiocb->co);
|
qemu_coroutine_enter(laiocb->co);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -722,7 +722,7 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||||
* @errp: Error object.
|
* @errp: Error object.
|
||||||
*
|
*
|
||||||
* Start a mirroring operation on @bs. Clusters that are allocated
|
* Start a mirroring operation on @bs. Clusters that are allocated
|
||||||
* in @bs will be written to @bs until the job is cancelled or
|
* in @bs will be written to @target until the job is cancelled or
|
||||||
* manually completed. At the end of a successful mirroring job,
|
* manually completed. At the end of a successful mirroring job,
|
||||||
* @bs will be switched to read from @target.
|
* @bs will be switched to read from @target.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -92,6 +92,19 @@ Coroutine *coroutine_fn qemu_coroutine_self(void);
|
||||||
*/
|
*/
|
||||||
bool qemu_in_coroutine(void);
|
bool qemu_in_coroutine(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the coroutine is currently entered
|
||||||
|
*
|
||||||
|
* A coroutine is "entered" if it has not yielded from the current
|
||||||
|
* qemu_coroutine_enter() call used to run it. This does not mean that the
|
||||||
|
* coroutine is currently executing code since it may have transferred control
|
||||||
|
* to another coroutine using qemu_coroutine_enter().
|
||||||
|
*
|
||||||
|
* When several coroutines enter each other there may be no way to know which
|
||||||
|
* ones have already been entered. In such situations this function can be
|
||||||
|
* used to avoid recursively entering coroutines.
|
||||||
|
*/
|
||||||
|
bool qemu_coroutine_entered(Coroutine *co);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -75,6 +75,9 @@ static void iothread_instance_finalize(Object *obj)
|
||||||
iothread_stop(obj, NULL);
|
iothread_stop(obj, NULL);
|
||||||
qemu_cond_destroy(&iothread->init_done_cond);
|
qemu_cond_destroy(&iothread->init_done_cond);
|
||||||
qemu_mutex_destroy(&iothread->init_done_lock);
|
qemu_mutex_destroy(&iothread->init_done_lock);
|
||||||
|
if (!iothread->ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
aio_context_unref(iothread->ctx);
|
aio_context_unref(iothread->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
|
||||||
|
|
||||||
for (i = 0; i < vq->size - 1; i++) {
|
for (i = 0; i < vq->size - 1; i++) {
|
||||||
/* vq->desc[i].addr */
|
/* vq->desc[i].addr */
|
||||||
writew(vq->desc + (16 * i), 0);
|
writeq(vq->desc + (16 * i), 0);
|
||||||
/* vq->desc[i].next */
|
/* vq->desc[i].next */
|
||||||
writew(vq->desc + (16 * i) + 14, i + 1);
|
writew(vq->desc + (16 * i) + 14, i + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,47 @@ static void test_self(void)
|
||||||
qemu_coroutine_enter(coroutine);
|
qemu_coroutine_enter(coroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that qemu_coroutine_entered() works
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void coroutine_fn verify_entered_step_2(void *opaque)
|
||||||
|
{
|
||||||
|
Coroutine *caller = (Coroutine *)opaque;
|
||||||
|
|
||||||
|
g_assert(qemu_coroutine_entered(caller));
|
||||||
|
g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
|
||||||
|
/* Once more to check it still works after yielding */
|
||||||
|
g_assert(qemu_coroutine_entered(caller));
|
||||||
|
g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void coroutine_fn verify_entered_step_1(void *opaque)
|
||||||
|
{
|
||||||
|
Coroutine *self = qemu_coroutine_self();
|
||||||
|
Coroutine *coroutine;
|
||||||
|
|
||||||
|
g_assert(qemu_coroutine_entered(self));
|
||||||
|
|
||||||
|
coroutine = qemu_coroutine_create(verify_entered_step_2, self);
|
||||||
|
g_assert(!qemu_coroutine_entered(coroutine));
|
||||||
|
qemu_coroutine_enter(coroutine);
|
||||||
|
g_assert(!qemu_coroutine_entered(coroutine));
|
||||||
|
qemu_coroutine_enter(coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_entered(void)
|
||||||
|
{
|
||||||
|
Coroutine *coroutine;
|
||||||
|
|
||||||
|
coroutine = qemu_coroutine_create(verify_entered_step_1, NULL);
|
||||||
|
g_assert(!qemu_coroutine_entered(coroutine));
|
||||||
|
qemu_coroutine_enter(coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that coroutines may nest multiple levels
|
* Check that coroutines may nest multiple levels
|
||||||
*/
|
*/
|
||||||
|
@ -389,6 +430,7 @@ int main(int argc, char **argv)
|
||||||
g_test_add_func("/basic/yield", test_yield);
|
g_test_add_func("/basic/yield", test_yield);
|
||||||
g_test_add_func("/basic/nesting", test_nesting);
|
g_test_add_func("/basic/nesting", test_nesting);
|
||||||
g_test_add_func("/basic/self", test_self);
|
g_test_add_func("/basic/self", test_self);
|
||||||
|
g_test_add_func("/basic/entered", test_entered);
|
||||||
g_test_add_func("/basic/in_coroutine", test_in_coroutine);
|
g_test_add_func("/basic/in_coroutine", test_in_coroutine);
|
||||||
g_test_add_func("/basic/order", test_order);
|
g_test_add_func("/basic/order", test_order);
|
||||||
if (g_test_perf()) {
|
if (g_test_perf()) {
|
||||||
|
|
|
@ -146,3 +146,8 @@ void coroutine_fn qemu_coroutine_yield(void)
|
||||||
self->caller = NULL;
|
self->caller = NULL;
|
||||||
qemu_coroutine_switch(self, to, COROUTINE_YIELD);
|
qemu_coroutine_switch(self, to, COROUTINE_YIELD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool qemu_coroutine_entered(Coroutine *co)
|
||||||
|
{
|
||||||
|
return co->caller;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue