提交 53343338 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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);
......
......@@ -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.
......
......@@ -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();
......
......@@ -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
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/main-loop.h"
AioContext *iohandler_get_aio_context(void)
{
abort();
}
......@@ -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();
}
......@@ -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);
......
......@@ -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;
}
......
......@@ -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) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册