summaryrefslogtreecommitdiffstats
path: root/util/qemu-coroutine-sleep.c
diff options
context:
space:
mode:
authorPeter Maydell2017-11-21 18:05:49 +0100
committerPeter Maydell2017-11-21 18:05:49 +0100
commit64807cd77938885f681a9a18b5736e923ad50b7c (patch)
tree7785670f2bc440477c5727b73766685017f6feee /util/qemu-coroutine-sleep.c
parentMerge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (diff)
parentqemu-iotest: add test for blockjob coroutine race condition (diff)
downloadqemu-64807cd77938885f681a9a18b5736e923ad50b7c.tar.gz
qemu-64807cd77938885f681a9a18b5736e923ad50b7c.tar.xz
qemu-64807cd77938885f681a9a18b5736e923ad50b7c.zip
Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging
# gpg: Signature made Tue 21 Nov 2017 17:01:33 GMT # gpg: using RSA key 0xBDBE7B27C0DE3057 # gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>" # gpg: aka "Jeffrey Cody <jeff@codyprime.org>" # gpg: aka "Jeffrey Cody <codyprime@gmail.com>" # Primary key fingerprint: 9957 4B4D 3474 90E7 9D98 D624 BDBE 7B27 C0DE 3057 * remotes/cody/tags/block-pull-request: qemu-iotest: add test for blockjob coroutine race condition qemu-iotests: add option in common.qemu for mismatch only coroutine: abort if we try to schedule or enter a pending coroutine blockjob: do not allow coroutine double entry or entry-after-completion Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/qemu-coroutine-sleep.c')
-rw-r--r--util/qemu-coroutine-sleep.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
index 9c5655041b..254349cdbb 100644
--- a/util/qemu-coroutine-sleep.c
+++ b/util/qemu-coroutine-sleep.c
@@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "qemu/coroutine.h"
+#include "qemu/coroutine_int.h"
#include "qemu/timer.h"
#include "block/aio.h"
@@ -25,6 +26,8 @@ static void co_sleep_cb(void *opaque)
{
CoSleepCB *sleep_cb = opaque;
+ /* Write of schedule protected by barrier write in aio_co_schedule */
+ atomic_set(&sleep_cb->co->scheduled, NULL);
aio_co_wake(sleep_cb->co);
}
@@ -34,6 +37,15 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
CoSleepCB sleep_cb = {
.co = qemu_coroutine_self(),
};
+
+ const char *scheduled = atomic_cmpxchg(&sleep_cb.co->scheduled, NULL,
+ __func__);
+ if (scheduled) {
+ fprintf(stderr,
+ "%s: Co-routine was already scheduled in '%s'\n",
+ __func__, scheduled);
+ abort();
+ }
sleep_cb.ts = aio_timer_new(ctx, type, SCALE_NS, co_sleep_cb, &sleep_cb);
timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns);
qemu_coroutine_yield();