aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-04-22 16:17:12 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-04-22 16:17:12 +0100
commit53343338a6e7b83777b82803398572b40afc8c0f (patch)
treea6b16ffcb414941d0cd6c63d0c7c3050a3a73451
parentee1e0f8e5d3682c561edcdceccff72b9d9b16d8b (diff)
parentab27c3b5e7408693dde0b565f050aa55c4a1bcef (diff)
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Mirror block job fixes for 2.6.0-rc4 # gpg: Signature made Fri 22 Apr 2016 15:46:41 BST using RSA key ID C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" * remotes/kevin/tags/for-upstream: mirror: Workaround for unexpected iohandler events during completion aio-posix: Skip external nodes in aio_dispatch virtio: Mark host notifiers as external event-notifier: Add "is_external" parameter iohandler: Introduce iohandler_get_aio_context Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--aio-posix.c8
-rw-r--r--block/mirror.c9
-rw-r--r--hw/usb/ccid-card-emulated.c2
-rw-r--r--hw/virtio/virtio.c8
-rw-r--r--include/qemu/event_notifier.h4
-rw-r--r--include/qemu/main-loop.h1
-rw-r--r--iohandler.c6
-rw-r--r--stubs/Makefile.objs1
-rw-r--r--stubs/iohandler.c8
-rw-r--r--stubs/set-fd-handler.c10
-rw-r--r--target-i386/hyperv.c6
-rw-r--r--util/event_notifier-posix.c4
-rw-r--r--util/event_notifier-win32.c1
13 files changed, 56 insertions, 12 deletions
diff --git a/aio-posix.c b/aio-posix.c
index 7fd565fbde..6006122e0b 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -282,10 +282,12 @@ bool aio_pending(AioContext *ctx)
int revents;
revents = node->pfd.revents & node->pfd.events;
- if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read) {
+ if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read &&
+ aio_node_check(ctx, node->is_external)) {
return true;
}
- if (revents & (G_IO_OUT | G_IO_ERR) && node->io_write) {
+ if (revents & (G_IO_OUT | G_IO_ERR) && node->io_write &&
+ aio_node_check(ctx, node->is_external)) {
return true;
}
}
@@ -323,6 +325,7 @@ bool aio_dispatch(AioContext *ctx)
if (!node->deleted &&
(revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
+ aio_node_check(ctx, node->is_external) &&
node->io_read) {
node->io_read(node->opaque);
@@ -333,6 +336,7 @@ bool aio_dispatch(AioContext *ctx)
}
if (!node->deleted &&
(revents & (G_IO_OUT | G_IO_ERR)) &&
+ aio_node_check(ctx, node->is_external) &&
node->io_write) {
node->io_write(node->opaque);
progress = true;
diff --git a/block/mirror.c b/block/mirror.c
index d56e30e472..039f48125e 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -495,6 +495,9 @@ out:
block_job_completed(&s->common, data->ret);
g_free(data);
bdrv_drained_end(src);
+ if (qemu_get_aio_context() == bdrv_get_aio_context(src)) {
+ aio_enable_external(iohandler_get_aio_context());
+ }
bdrv_unref(src);
}
@@ -716,6 +719,12 @@ immediate_exit:
/* Before we switch to target in mirror_exit, make sure data doesn't
* change. */
bdrv_drained_begin(s->common.bs);
+ if (qemu_get_aio_context() == bdrv_get_aio_context(bs)) {
+ /* FIXME: virtio host notifiers run on iohandler_ctx, therefore the
+ * above bdrv_drained_end isn't enough to quiesce it. This is ugly, we
+ * need a block layer API change to achieve this. */
+ aio_disable_external(iohandler_get_aio_context());
+ }
block_job_defer_to_main_loop(&s->common, mirror_exit, data);
}
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 9ddd5ad75b..3213f9f8af 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -407,7 +407,7 @@ static int init_event_notifier(EmulatedState *card)
DPRINTF(card, 2, "event notifier creation failed\n");
return -1;
}
- event_notifier_set_handler(&card->notifier, card_event_handler);
+ event_notifier_set_handler(&card->notifier, false, card_event_handler);
return 0;
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index f745c4abd0..30ede3d1cc 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1775,10 +1775,10 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
bool with_irqfd)
{
if (assign && !with_irqfd) {
- event_notifier_set_handler(&vq->guest_notifier,
+ event_notifier_set_handler(&vq->guest_notifier, false,
virtio_queue_guest_notifier_read);
} else {
- event_notifier_set_handler(&vq->guest_notifier, NULL);
+ event_notifier_set_handler(&vq->guest_notifier, false, NULL);
}
if (!assign) {
/* Test and clear notifier before closing it,
@@ -1829,10 +1829,10 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
bool set_handler)
{
if (assign && set_handler) {
- event_notifier_set_handler(&vq->host_notifier,
+ event_notifier_set_handler(&vq->host_notifier, true,
virtio_queue_host_notifier_read);
} else {
- event_notifier_set_handler(&vq->host_notifier, NULL);
+ event_notifier_set_handler(&vq->host_notifier, true, NULL);
}
if (!assign) {
/* Test and clear notifier before after disabling event,
diff --git a/include/qemu/event_notifier.h b/include/qemu/event_notifier.h
index a8f28540c9..e326990db4 100644
--- a/include/qemu/event_notifier.h
+++ b/include/qemu/event_notifier.h
@@ -34,7 +34,9 @@ int event_notifier_init(EventNotifier *, int active);
void event_notifier_cleanup(EventNotifier *);
int event_notifier_set(EventNotifier *);
int event_notifier_test_and_clear(EventNotifier *);
-int event_notifier_set_handler(EventNotifier *, EventNotifierHandler *);
+int event_notifier_set_handler(EventNotifier *,
+ bool is_external,
+ EventNotifierHandler *);
#ifdef CONFIG_POSIX
void event_notifier_init_fd(EventNotifier *, int fd);
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 99769093fc..19b5de3dd5 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -204,6 +204,7 @@ void qemu_set_fd_handler(int fd,
void *opaque);
GSource *iohandler_get_g_source(void);
+AioContext *iohandler_get_aio_context(void);
#ifdef CONFIG_POSIX
/**
* qemu_add_child_watch: Register a child process for reaping.
diff --git a/iohandler.c b/iohandler.c
index 3f23433b5a..f2fc8a9bd6 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -44,6 +44,12 @@ static void iohandler_init(void)
}
}
+AioContext *iohandler_get_aio_context(void)
+{
+ iohandler_init();
+ return iohandler_ctx;
+}
+
GSource *iohandler_get_g_source(void)
{
iohandler_init();
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index b6d1e650db..4b258a6731 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -40,3 +40,4 @@ stub-obj-y += qmp_pc_dimm_device_list.o
stub-obj-y += target-monitor-defs.o
stub-obj-y += target-get-monitor-def.o
stub-obj-y += vhost.o
+stub-obj-y += iohandler.o
diff --git a/stubs/iohandler.c b/stubs/iohandler.c
new file mode 100644
index 0000000000..22b0ee5b0a
--- /dev/null
+++ b/stubs/iohandler.c
@@ -0,0 +1,8 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/main-loop.h"
+
+AioContext *iohandler_get_aio_context(void)
+{
+ abort();
+}
diff --git a/stubs/set-fd-handler.c b/stubs/set-fd-handler.c
index 26965de4c3..06a5da48f1 100644
--- a/stubs/set-fd-handler.c
+++ b/stubs/set-fd-handler.c
@@ -9,3 +9,13 @@ void qemu_set_fd_handler(int fd,
{
abort();
}
+
+void aio_set_fd_handler(AioContext *ctx,
+ int fd,
+ bool is_external,
+ IOHandler *io_read,
+ IOHandler *io_write,
+ void *opaque)
+{
+ abort();
+}
diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c
index c4d6a9b2b1..39a230f119 100644
--- a/target-i386/hyperv.c
+++ b/target-i386/hyperv.c
@@ -88,7 +88,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
goto err_sint_set_notifier;
}
- event_notifier_set_handler(&sint_route->sint_ack_notifier,
+ event_notifier_set_handler(&sint_route->sint_ack_notifier, false,
kvm_hv_sint_ack_handler);
gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint);
@@ -112,7 +112,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
err_irqfd:
kvm_irqchip_release_virq(kvm_state, gsi);
err_gsi:
- event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL);
+ event_notifier_set_handler(&sint_route->sint_ack_notifier, false, NULL);
event_notifier_cleanup(&sint_route->sint_ack_notifier);
err_sint_set_notifier:
event_notifier_cleanup(&sint_route->sint_set_notifier);
@@ -128,7 +128,7 @@ void kvm_hv_sint_route_destroy(HvSintRoute *sint_route)
&sint_route->sint_set_notifier,
sint_route->gsi);
kvm_irqchip_release_virq(kvm_state, sint_route->gsi);
- event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL);
+ event_notifier_set_handler(&sint_route->sint_ack_notifier, false, NULL);
event_notifier_cleanup(&sint_route->sint_ack_notifier);
event_notifier_cleanup(&sint_route->sint_set_notifier);
g_free(sint_route);
diff --git a/util/event_notifier-posix.c b/util/event_notifier-posix.c
index e150301c33..c1f0d79b34 100644
--- a/util/event_notifier-posix.c
+++ b/util/event_notifier-posix.c
@@ -91,9 +91,11 @@ int event_notifier_get_fd(const EventNotifier *e)
}
int event_notifier_set_handler(EventNotifier *e,
+ bool is_external,
EventNotifierHandler *handler)
{
- qemu_set_fd_handler(e->rfd, (IOHandler *)handler, NULL, e);
+ aio_set_fd_handler(iohandler_get_aio_context(), e->rfd, is_external,
+ (IOHandler *)handler, NULL, e);
return 0;
}
diff --git a/util/event_notifier-win32.c b/util/event_notifier-win32.c
index 14b4f7d2c0..de87df02d6 100644
--- a/util/event_notifier-win32.c
+++ b/util/event_notifier-win32.c
@@ -33,6 +33,7 @@ HANDLE event_notifier_get_handle(EventNotifier *e)
}
int event_notifier_set_handler(EventNotifier *e,
+ bool is_external,
EventNotifierHandler *handler)
{
if (handler) {