mirror of https://gitee.com/openkylin/qemu.git
linux-aio: use event notifiers
Since linux-aio already uses an eventfd, converting it to use the EventNotifier-based API simplifies the code even though it is not meant to be portable. Reviewed-by: Anthony Liguori <anthony@codemonkey.ws> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
22bfa75eaf
commit
c90caf25e2
49
linux-aio.c
49
linux-aio.c
|
@ -11,8 +11,8 @@
|
||||||
#include "qemu-aio.h"
|
#include "qemu-aio.h"
|
||||||
#include "qemu-queue.h"
|
#include "qemu-queue.h"
|
||||||
#include "block/raw-posix-aio.h"
|
#include "block/raw-posix-aio.h"
|
||||||
|
#include "event_notifier.h"
|
||||||
|
|
||||||
#include <sys/eventfd.h>
|
|
||||||
#include <libaio.h>
|
#include <libaio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -38,7 +38,7 @@ struct qemu_laiocb {
|
||||||
|
|
||||||
struct qemu_laio_state {
|
struct qemu_laio_state {
|
||||||
io_context_t ctx;
|
io_context_t ctx;
|
||||||
int efd;
|
EventNotifier e;
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,29 +77,17 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
|
||||||
qemu_aio_release(laiocb);
|
qemu_aio_release(laiocb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemu_laio_completion_cb(void *opaque)
|
static void qemu_laio_completion_cb(EventNotifier *e)
|
||||||
{
|
{
|
||||||
struct qemu_laio_state *s = opaque;
|
struct qemu_laio_state *s = container_of(e, struct qemu_laio_state, e);
|
||||||
|
|
||||||
while (1) {
|
while (event_notifier_test_and_clear(&s->e)) {
|
||||||
struct io_event events[MAX_EVENTS];
|
struct io_event events[MAX_EVENTS];
|
||||||
uint64_t val;
|
|
||||||
ssize_t ret;
|
|
||||||
struct timespec ts = { 0 };
|
struct timespec ts = { 0 };
|
||||||
int nevents, i;
|
int nevents, i;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = read(s->efd, &val, sizeof(val));
|
nevents = io_getevents(s->ctx, MAX_EVENTS, MAX_EVENTS, events, &ts);
|
||||||
} while (ret == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
if (ret == -1 && errno == EAGAIN)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ret != 8)
|
|
||||||
break;
|
|
||||||
|
|
||||||
do {
|
|
||||||
nevents = io_getevents(s->ctx, val, MAX_EVENTS, events, &ts);
|
|
||||||
} while (nevents == -EINTR);
|
} while (nevents == -EINTR);
|
||||||
|
|
||||||
for (i = 0; i < nevents; i++) {
|
for (i = 0; i < nevents; i++) {
|
||||||
|
@ -113,9 +101,9 @@ static void qemu_laio_completion_cb(void *opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemu_laio_flush_cb(void *opaque)
|
static int qemu_laio_flush_cb(EventNotifier *e)
|
||||||
{
|
{
|
||||||
struct qemu_laio_state *s = opaque;
|
struct qemu_laio_state *s = container_of(e, struct qemu_laio_state, e);
|
||||||
|
|
||||||
return (s->count > 0) ? 1 : 0;
|
return (s->count > 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
@ -147,8 +135,9 @@ static void laio_cancel(BlockDriverAIOCB *blockacb)
|
||||||
* We might be able to do this slightly more optimal by removing the
|
* We might be able to do this slightly more optimal by removing the
|
||||||
* O_NONBLOCK flag.
|
* O_NONBLOCK flag.
|
||||||
*/
|
*/
|
||||||
while (laiocb->ret == -EINPROGRESS)
|
while (laiocb->ret == -EINPROGRESS) {
|
||||||
qemu_laio_completion_cb(laiocb->ctx);
|
qemu_laio_completion_cb(&laiocb->ctx->e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static AIOPool laio_pool = {
|
static AIOPool laio_pool = {
|
||||||
|
@ -187,7 +176,7 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
|
||||||
__func__, type);
|
__func__, type);
|
||||||
goto out_free_aiocb;
|
goto out_free_aiocb;
|
||||||
}
|
}
|
||||||
io_set_eventfd(&laiocb->iocb, s->efd);
|
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
|
||||||
s->count++;
|
s->count++;
|
||||||
|
|
||||||
if (io_submit(s->ctx, 1, &iocbs) < 0)
|
if (io_submit(s->ctx, 1, &iocbs) < 0)
|
||||||
|
@ -206,21 +195,21 @@ void *laio_init(void)
|
||||||
struct qemu_laio_state *s;
|
struct qemu_laio_state *s;
|
||||||
|
|
||||||
s = g_malloc0(sizeof(*s));
|
s = g_malloc0(sizeof(*s));
|
||||||
s->efd = eventfd(0, 0);
|
if (event_notifier_init(&s->e, false) < 0) {
|
||||||
if (s->efd == -1)
|
|
||||||
goto out_free_state;
|
goto out_free_state;
|
||||||
fcntl(s->efd, F_SETFL, O_NONBLOCK);
|
}
|
||||||
|
|
||||||
if (io_setup(MAX_EVENTS, &s->ctx) != 0)
|
if (io_setup(MAX_EVENTS, &s->ctx) != 0) {
|
||||||
goto out_close_efd;
|
goto out_close_efd;
|
||||||
|
}
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb, NULL,
|
qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb,
|
||||||
qemu_laio_flush_cb, s);
|
qemu_laio_flush_cb);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
out_close_efd:
|
out_close_efd:
|
||||||
close(s->efd);
|
event_notifier_cleanup(&s->e);
|
||||||
out_free_state:
|
out_free_state:
|
||||||
g_free(s);
|
g_free(s);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue