diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-04-22 16:17:12 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-04-22 16:17:12 +0100 |
commit | 53343338a6e7b83777b82803398572b40afc8c0f (patch) | |
tree | a6b16ffcb414941d0cd6c63d0c7c3050a3a73451 | |
parent | ee1e0f8e5d3682c561edcdceccff72b9d9b16d8b (diff) | |
parent | ab27c3b5e7408693dde0b565f050aa55c4a1bcef (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.c | 8 | ||||
-rw-r--r-- | block/mirror.c | 9 | ||||
-rw-r--r-- | hw/usb/ccid-card-emulated.c | 2 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 8 | ||||
-rw-r--r-- | include/qemu/event_notifier.h | 4 | ||||
-rw-r--r-- | include/qemu/main-loop.h | 1 | ||||
-rw-r--r-- | iohandler.c | 6 | ||||
-rw-r--r-- | stubs/Makefile.objs | 1 | ||||
-rw-r--r-- | stubs/iohandler.c | 8 | ||||
-rw-r--r-- | stubs/set-fd-handler.c | 10 | ||||
-rw-r--r-- | target-i386/hyperv.c | 6 | ||||
-rw-r--r-- | util/event_notifier-posix.c | 4 | ||||
-rw-r--r-- | util/event_notifier-win32.c | 1 |
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) { |