mirror of https://github.com/xemu-project/xemu.git
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 iQEcBAABAgAGBQJXjQqzAAoJEJykq7OBq3PIqvUH/1HFZxTfmtQ2g3i6b7D63Bj8 f5FHRZ8XCaBdIGKJO8/nY4TdwOswXKuomdrvSz9QtJRD/WgRDZQ30jrPPaq9P9+m GXfgWMtFWeYSOkRKtOtxJ+2pwHr0I0qmVBCDAwIgak9Yx+uP/KowEIibeybbPuQ+ LXAWlw+LWGOV/XaZQyY6dgAUaXTJ+t86WyZL6cGR3JOMETmpYsFzzyO1379ZstY3 +mcuAmmrjdV0B9l3rghKjfAooV3MmMAecsX5mizPsBgI29k7tvLEAnLHIoam7E0b brFL6vGoyhprDO0soR3ZqclSIQYdyQDTpV6vUjLnpg/z1SdQOCoccn7k7B7Hr3Q= =NoOD -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging # gpg: Signature made Mon 18 Jul 2016 17:58:27 BST # gpg: using RSA key 0x9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/block-pull-request: MAINTAINERS: Add include/block/aio.h to block I/O path section virtio-blk: dataplane cleanup checkpatch: consider git extended headers valid patches aio-posix: remove useless parameter linux-aio: prevent submitting more than MAX_EVENTS aio_ctx_check: follow CODING_STYLE linux-aio: share one LinuxAioState within an AioContext spec/parallels: fix a mistake Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
a098fbc025
|
@ -1027,6 +1027,7 @@ F: async.c
|
||||||
F: aio-*.c
|
F: aio-*.c
|
||||||
F: block/io.c
|
F: block/io.c
|
||||||
F: migration/block*
|
F: migration/block*
|
||||||
|
F: include/block/aio.h
|
||||||
T: git git://github.com/stefanha/qemu.git block
|
T: git git://github.com/stefanha/qemu.git block
|
||||||
|
|
||||||
Block Jobs
|
Block Jobs
|
||||||
|
|
|
@ -485,12 +485,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aio_context_setup(AioContext *ctx, Error **errp)
|
void aio_context_setup(AioContext *ctx)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_EPOLL_CREATE1
|
#ifdef CONFIG_EPOLL_CREATE1
|
||||||
assert(!ctx->epollfd);
|
assert(!ctx->epollfd);
|
||||||
ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
|
ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
|
||||||
if (ctx->epollfd == -1) {
|
if (ctx->epollfd == -1) {
|
||||||
|
fprintf(stderr, "Failed to create epoll instance: %s", strerror(errno));
|
||||||
ctx->epoll_available = false;
|
ctx->epoll_available = false;
|
||||||
} else {
|
} else {
|
||||||
ctx->epoll_available = true;
|
ctx->epoll_available = true;
|
||||||
|
|
|
@ -371,6 +371,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aio_context_setup(AioContext *ctx, Error **errp)
|
void aio_context_setup(AioContext *ctx)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
33
async.c
33
async.c
|
@ -29,6 +29,7 @@
|
||||||
#include "block/thread-pool.h"
|
#include "block/thread-pool.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/atomic.h"
|
#include "qemu/atomic.h"
|
||||||
|
#include "block/raw-aio.h"
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* bottom halves (can be seen as timers which expire ASAP) */
|
/* bottom halves (can be seen as timers which expire ASAP) */
|
||||||
|
@ -217,7 +218,7 @@ aio_ctx_check(GSource *source)
|
||||||
for (bh = ctx->first_bh; bh; bh = bh->next) {
|
for (bh = ctx->first_bh; bh; bh = bh->next) {
|
||||||
if (!bh->deleted && bh->scheduled) {
|
if (!bh->deleted && bh->scheduled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0);
|
return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0);
|
||||||
}
|
}
|
||||||
|
@ -242,6 +243,14 @@ aio_ctx_finalize(GSource *source)
|
||||||
qemu_bh_delete(ctx->notify_dummy_bh);
|
qemu_bh_delete(ctx->notify_dummy_bh);
|
||||||
thread_pool_free(ctx->thread_pool);
|
thread_pool_free(ctx->thread_pool);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
if (ctx->linux_aio) {
|
||||||
|
laio_detach_aio_context(ctx->linux_aio, ctx);
|
||||||
|
laio_cleanup(ctx->linux_aio);
|
||||||
|
ctx->linux_aio = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
qemu_mutex_lock(&ctx->bh_lock);
|
qemu_mutex_lock(&ctx->bh_lock);
|
||||||
while (ctx->first_bh) {
|
while (ctx->first_bh) {
|
||||||
QEMUBH *next = ctx->first_bh->next;
|
QEMUBH *next = ctx->first_bh->next;
|
||||||
|
@ -282,6 +291,17 @@ ThreadPool *aio_get_thread_pool(AioContext *ctx)
|
||||||
return ctx->thread_pool;
|
return ctx->thread_pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
LinuxAioState *aio_get_linux_aio(AioContext *ctx)
|
||||||
|
{
|
||||||
|
if (!ctx->linux_aio) {
|
||||||
|
ctx->linux_aio = laio_init();
|
||||||
|
laio_attach_aio_context(ctx->linux_aio, ctx);
|
||||||
|
}
|
||||||
|
return ctx->linux_aio;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void aio_notify(AioContext *ctx)
|
void aio_notify(AioContext *ctx)
|
||||||
{
|
{
|
||||||
/* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs
|
/* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs
|
||||||
|
@ -327,14 +347,10 @@ AioContext *aio_context_new(Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AioContext *ctx;
|
AioContext *ctx;
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
|
ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
|
||||||
aio_context_setup(ctx, &local_err);
|
aio_context_setup(ctx);
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ret = event_notifier_init(&ctx->notifier, false);
|
ret = event_notifier_init(&ctx->notifier, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret, "Failed to initialize event notifier");
|
error_setg_errno(errp, -ret, "Failed to initialize event notifier");
|
||||||
|
@ -345,6 +361,9 @@ AioContext *aio_context_new(Error **errp)
|
||||||
false,
|
false,
|
||||||
(EventNotifierHandler *)
|
(EventNotifierHandler *)
|
||||||
event_notifier_dummy_cb);
|
event_notifier_dummy_cb);
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
ctx->linux_aio = NULL;
|
||||||
|
#endif
|
||||||
ctx->thread_pool = NULL;
|
ctx->thread_pool = NULL;
|
||||||
qemu_mutex_init(&ctx->bh_lock);
|
qemu_mutex_init(&ctx->bh_lock);
|
||||||
rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
|
rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_EVENTS 128
|
#define MAX_EVENTS 128
|
||||||
|
|
||||||
#define MAX_QUEUED_IO 128
|
|
||||||
|
|
||||||
struct qemu_laiocb {
|
struct qemu_laiocb {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
|
@ -44,12 +42,15 @@ struct qemu_laiocb {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int plugged;
|
int plugged;
|
||||||
unsigned int n;
|
unsigned int in_queue;
|
||||||
|
unsigned int in_flight;
|
||||||
bool blocked;
|
bool blocked;
|
||||||
QSIMPLEQ_HEAD(, qemu_laiocb) pending;
|
QSIMPLEQ_HEAD(, qemu_laiocb) pending;
|
||||||
} LaioQueue;
|
} LaioQueue;
|
||||||
|
|
||||||
struct LinuxAioState {
|
struct LinuxAioState {
|
||||||
|
AioContext *aio_context;
|
||||||
|
|
||||||
io_context_t ctx;
|
io_context_t ctx;
|
||||||
EventNotifier e;
|
EventNotifier e;
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ static void qemu_laio_completion_bh(void *opaque)
|
||||||
s->event_max = 0;
|
s->event_max = 0;
|
||||||
return; /* no more events */
|
return; /* no more events */
|
||||||
}
|
}
|
||||||
|
s->io_q.in_flight -= s->event_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reschedule so nested event loops see currently pending completions */
|
/* Reschedule so nested event loops see currently pending completions */
|
||||||
|
@ -190,7 +192,8 @@ static void ioq_init(LaioQueue *io_q)
|
||||||
{
|
{
|
||||||
QSIMPLEQ_INIT(&io_q->pending);
|
QSIMPLEQ_INIT(&io_q->pending);
|
||||||
io_q->plugged = 0;
|
io_q->plugged = 0;
|
||||||
io_q->n = 0;
|
io_q->in_queue = 0;
|
||||||
|
io_q->in_flight = 0;
|
||||||
io_q->blocked = false;
|
io_q->blocked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,14 +201,17 @@ static void ioq_submit(LinuxAioState *s)
|
||||||
{
|
{
|
||||||
int ret, len;
|
int ret, len;
|
||||||
struct qemu_laiocb *aiocb;
|
struct qemu_laiocb *aiocb;
|
||||||
struct iocb *iocbs[MAX_QUEUED_IO];
|
struct iocb *iocbs[MAX_EVENTS];
|
||||||
QSIMPLEQ_HEAD(, qemu_laiocb) completed;
|
QSIMPLEQ_HEAD(, qemu_laiocb) completed;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (s->io_q.in_flight >= MAX_EVENTS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
len = 0;
|
len = 0;
|
||||||
QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) {
|
QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) {
|
||||||
iocbs[len++] = &aiocb->iocb;
|
iocbs[len++] = &aiocb->iocb;
|
||||||
if (len == MAX_QUEUED_IO) {
|
if (s->io_q.in_flight + len >= MAX_EVENTS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,24 +224,24 @@ static void ioq_submit(LinuxAioState *s)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
s->io_q.n -= ret;
|
s->io_q.in_flight += ret;
|
||||||
|
s->io_q.in_queue -= ret;
|
||||||
aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb);
|
aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb);
|
||||||
QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed);
|
QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed);
|
||||||
} while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
|
} while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
|
||||||
s->io_q.blocked = (s->io_q.n > 0);
|
s->io_q.blocked = (s->io_q.in_queue > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s)
|
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s)
|
||||||
{
|
{
|
||||||
assert(!s->io_q.plugged);
|
s->io_q.plugged++;
|
||||||
s->io_q.plugged = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s)
|
void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s)
|
||||||
{
|
{
|
||||||
assert(s->io_q.plugged);
|
assert(s->io_q.plugged);
|
||||||
s->io_q.plugged = 0;
|
if (--s->io_q.plugged == 0 &&
|
||||||
if (!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
|
!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
|
||||||
ioq_submit(s);
|
ioq_submit(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,9 +269,10 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||||
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
|
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
|
||||||
|
|
||||||
QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
|
QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
|
||||||
s->io_q.n++;
|
s->io_q.in_queue++;
|
||||||
if (!s->io_q.blocked &&
|
if (!s->io_q.blocked &&
|
||||||
(!s->io_q.plugged || s->io_q.n >= MAX_QUEUED_IO)) {
|
(!s->io_q.plugged ||
|
||||||
|
s->io_q.in_flight + s->io_q.in_queue >= MAX_EVENTS)) {
|
||||||
ioq_submit(s);
|
ioq_submit(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,6 +332,7 @@ void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context)
|
||||||
|
|
||||||
void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context)
|
void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context)
|
||||||
{
|
{
|
||||||
|
s->aio_context = new_context;
|
||||||
s->completion_bh = aio_bh_new(new_context, qemu_laio_completion_bh, s);
|
s->completion_bh = aio_bh_new(new_context, qemu_laio_completion_bh, s);
|
||||||
aio_set_event_notifier(new_context, &s->e, false,
|
aio_set_event_notifier(new_context, &s->e, false,
|
||||||
qemu_laio_completion_cb);
|
qemu_laio_completion_cb);
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "block/thread-pool.h"
|
#include "block/thread-pool.h"
|
||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
#include "raw-aio.h"
|
#include "block/raw-aio.h"
|
||||||
#include "qapi/util.h"
|
#include "qapi/util.h"
|
||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
|
|
||||||
|
@ -137,10 +137,6 @@ typedef struct BDRVRawState {
|
||||||
int open_flags;
|
int open_flags;
|
||||||
size_t buf_align;
|
size_t buf_align;
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
int use_aio;
|
|
||||||
LinuxAioState *aio_ctx;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_XFS
|
#ifdef CONFIG_XFS
|
||||||
bool is_xfs:1;
|
bool is_xfs:1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -154,9 +150,6 @@ typedef struct BDRVRawState {
|
||||||
typedef struct BDRVRawReopenState {
|
typedef struct BDRVRawReopenState {
|
||||||
int fd;
|
int fd;
|
||||||
int open_flags;
|
int open_flags;
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
int use_aio;
|
|
||||||
#endif
|
|
||||||
} BDRVRawReopenState;
|
} BDRVRawReopenState;
|
||||||
|
|
||||||
static int fd_open(BlockDriverState *bs);
|
static int fd_open(BlockDriverState *bs);
|
||||||
|
@ -374,58 +367,15 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raw_detach_aio_context(BlockDriverState *bs)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
BDRVRawState *s = bs->opaque;
|
static bool raw_use_aio(int bdrv_flags)
|
||||||
|
|
||||||
if (s->use_aio) {
|
|
||||||
laio_detach_aio_context(s->aio_ctx, bdrv_get_aio_context(bs));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void raw_attach_aio_context(BlockDriverState *bs,
|
|
||||||
AioContext *new_context)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
BDRVRawState *s = bs->opaque;
|
|
||||||
|
|
||||||
if (s->use_aio) {
|
|
||||||
laio_attach_aio_context(s->aio_ctx, new_context);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
static int raw_set_aio(LinuxAioState **aio_ctx, int *use_aio, int bdrv_flags)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
assert(aio_ctx != NULL);
|
|
||||||
assert(use_aio != NULL);
|
|
||||||
/*
|
/*
|
||||||
* Currently Linux do AIO only for files opened with O_DIRECT
|
* Currently Linux do AIO only for files opened with O_DIRECT
|
||||||
* specified so check NOCACHE flag too
|
* specified so check NOCACHE flag too
|
||||||
*/
|
*/
|
||||||
if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
|
return (bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
|
||||||
(BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
|
(BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO);
|
||||||
|
|
||||||
/* if non-NULL, laio_init() has already been run */
|
|
||||||
if (*aio_ctx == NULL) {
|
|
||||||
*aio_ctx = laio_init();
|
|
||||||
if (!*aio_ctx) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*use_aio = 1;
|
|
||||||
} else {
|
|
||||||
*use_aio = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -494,13 +444,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) {
|
if (!raw_use_aio(bdrv_flags) && (bdrv_flags & BDRV_O_NATIVE_AIO)) {
|
||||||
qemu_close(fd);
|
|
||||||
ret = -errno;
|
|
||||||
error_setg_errno(errp, -ret, "Could not set AIO state");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!s->use_aio && (bdrv_flags & BDRV_O_NATIVE_AIO)) {
|
|
||||||
error_setg(errp, "aio=native was specified, but it requires "
|
error_setg(errp, "aio=native was specified, but it requires "
|
||||||
"cache.direct=on, which was not specified.");
|
"cache.direct=on, which was not specified.");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -567,8 +511,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
raw_attach_aio_context(bs, bdrv_get_aio_context(bs));
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
fail:
|
fail:
|
||||||
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
|
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
|
||||||
|
@ -603,18 +545,6 @@ static int raw_reopen_prepare(BDRVReopenState *state,
|
||||||
state->opaque = g_new0(BDRVRawReopenState, 1);
|
state->opaque = g_new0(BDRVRawReopenState, 1);
|
||||||
raw_s = state->opaque;
|
raw_s = state->opaque;
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
raw_s->use_aio = s->use_aio;
|
|
||||||
|
|
||||||
/* we can use s->aio_ctx instead of a copy, because the use_aio flag is
|
|
||||||
* valid in the 'false' condition even if aio_ctx is set, and raw_set_aio()
|
|
||||||
* won't override aio_ctx if aio_ctx is non-NULL */
|
|
||||||
if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) {
|
|
||||||
error_setg(errp, "Could not set AIO state");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (s->type == FTYPE_CD) {
|
if (s->type == FTYPE_CD) {
|
||||||
raw_s->open_flags |= O_NONBLOCK;
|
raw_s->open_flags |= O_NONBLOCK;
|
||||||
}
|
}
|
||||||
|
@ -689,9 +619,6 @@ static void raw_reopen_commit(BDRVReopenState *state)
|
||||||
|
|
||||||
qemu_close(s->fd);
|
qemu_close(s->fd);
|
||||||
s->fd = raw_s->fd;
|
s->fd = raw_s->fd;
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
s->use_aio = raw_s->use_aio;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_free(state->opaque);
|
g_free(state->opaque);
|
||||||
state->opaque = NULL;
|
state->opaque = NULL;
|
||||||
|
@ -1329,9 +1256,10 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
|
||||||
if (!bdrv_qiov_is_aligned(bs, qiov)) {
|
if (!bdrv_qiov_is_aligned(bs, qiov)) {
|
||||||
type |= QEMU_AIO_MISALIGNED;
|
type |= QEMU_AIO_MISALIGNED;
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
} else if (s->use_aio) {
|
} else if (bs->open_flags & BDRV_O_NATIVE_AIO) {
|
||||||
|
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||||
assert(qiov->size == bytes);
|
assert(qiov->size == bytes);
|
||||||
return laio_co_submit(bs, s->aio_ctx, s->fd, offset, qiov, type);
|
return laio_co_submit(bs, aio, s->fd, offset, qiov, type);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1357,9 +1285,9 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||||
static void raw_aio_plug(BlockDriverState *bs)
|
static void raw_aio_plug(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
BDRVRawState *s = bs->opaque;
|
if (bs->open_flags & BDRV_O_NATIVE_AIO) {
|
||||||
if (s->use_aio) {
|
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||||
laio_io_plug(bs, s->aio_ctx);
|
laio_io_plug(bs, aio);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1367,9 +1295,9 @@ static void raw_aio_plug(BlockDriverState *bs)
|
||||||
static void raw_aio_unplug(BlockDriverState *bs)
|
static void raw_aio_unplug(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
BDRVRawState *s = bs->opaque;
|
if (bs->open_flags & BDRV_O_NATIVE_AIO) {
|
||||||
if (s->use_aio) {
|
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||||
laio_io_unplug(bs, s->aio_ctx);
|
laio_io_unplug(bs, aio);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1389,13 +1317,6 @@ static void raw_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
raw_detach_aio_context(bs);
|
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
if (s->use_aio) {
|
|
||||||
laio_cleanup(s->aio_ctx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (s->fd >= 0) {
|
if (s->fd >= 0) {
|
||||||
qemu_close(s->fd);
|
qemu_close(s->fd);
|
||||||
s->fd = -1;
|
s->fd = -1;
|
||||||
|
@ -1954,9 +1875,6 @@ BlockDriver bdrv_file = {
|
||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
.bdrv_detach_aio_context = raw_detach_aio_context,
|
|
||||||
.bdrv_attach_aio_context = raw_attach_aio_context,
|
|
||||||
|
|
||||||
.create_opts = &raw_create_opts,
|
.create_opts = &raw_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2402,9 +2320,6 @@ static BlockDriver bdrv_host_device = {
|
||||||
.bdrv_probe_blocksizes = hdev_probe_blocksizes,
|
.bdrv_probe_blocksizes = hdev_probe_blocksizes,
|
||||||
.bdrv_probe_geometry = hdev_probe_geometry,
|
.bdrv_probe_geometry = hdev_probe_geometry,
|
||||||
|
|
||||||
.bdrv_detach_aio_context = raw_detach_aio_context,
|
|
||||||
.bdrv_attach_aio_context = raw_attach_aio_context,
|
|
||||||
|
|
||||||
/* generic scsi device */
|
/* generic scsi device */
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
.bdrv_aio_ioctl = hdev_aio_ioctl,
|
.bdrv_aio_ioctl = hdev_aio_ioctl,
|
||||||
|
@ -2524,9 +2439,6 @@ static BlockDriver bdrv_host_cdrom = {
|
||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
.bdrv_detach_aio_context = raw_detach_aio_context,
|
|
||||||
.bdrv_attach_aio_context = raw_attach_aio_context,
|
|
||||||
|
|
||||||
/* removable device support */
|
/* removable device support */
|
||||||
.bdrv_is_inserted = cdrom_is_inserted,
|
.bdrv_is_inserted = cdrom_is_inserted,
|
||||||
.bdrv_eject = cdrom_eject,
|
.bdrv_eject = cdrom_eject,
|
||||||
|
@ -2657,9 +2569,6 @@ static BlockDriver bdrv_host_cdrom = {
|
||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
.bdrv_detach_aio_context = raw_detach_aio_context,
|
|
||||||
.bdrv_attach_aio_context = raw_attach_aio_context,
|
|
||||||
|
|
||||||
/* removable device support */
|
/* removable device support */
|
||||||
.bdrv_is_inserted = cdrom_is_inserted,
|
.bdrv_is_inserted = cdrom_is_inserted,
|
||||||
.bdrv_eject = cdrom_eject,
|
.bdrv_eject = cdrom_eject,
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "raw-aio.h"
|
#include "block/raw-aio.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "block/thread-pool.h"
|
#include "block/thread-pool.h"
|
||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "block/aio.h"
|
#include "block/aio.h"
|
||||||
#include "raw-aio.h"
|
#include "block/raw-aio.h"
|
||||||
#include "qemu/event_notifier.h"
|
#include "qemu/event_notifier.h"
|
||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
|
@ -94,7 +94,7 @@ Bytes:
|
||||||
Bit 0: Empty Image bit. If set, the image should be
|
Bit 0: Empty Image bit. If set, the image should be
|
||||||
considered clear.
|
considered clear.
|
||||||
|
|
||||||
Bits 2-31: Unused.
|
Bits 1-31: Unused.
|
||||||
|
|
||||||
56 - 63: ext_off
|
56 - 63: ext_off
|
||||||
Format Extension offset, an offset, in sectors, from the start of
|
Format Extension offset, an offset, in sectors, from the start of
|
||||||
|
|
|
@ -112,10 +112,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
|
||||||
s->vdev = vdev;
|
s->vdev = vdev;
|
||||||
s->conf = conf;
|
s->conf = conf;
|
||||||
|
|
||||||
if (conf->iothread) {
|
s->iothread = conf->iothread;
|
||||||
s->iothread = conf->iothread;
|
object_ref(OBJECT(s->iothread));
|
||||||
object_ref(OBJECT(s->iothread));
|
|
||||||
}
|
|
||||||
s->ctx = iothread_get_aio_context(s->iothread);
|
s->ctx = iothread_get_aio_context(s->iothread);
|
||||||
s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
|
s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
|
||||||
s->batch_notify_vqs = bitmap_new(conf->num_queues);
|
s->batch_notify_vqs = bitmap_new(conf->num_queues);
|
||||||
|
|
|
@ -47,6 +47,9 @@ typedef struct AioHandler AioHandler;
|
||||||
typedef void QEMUBHFunc(void *opaque);
|
typedef void QEMUBHFunc(void *opaque);
|
||||||
typedef void IOHandler(void *opaque);
|
typedef void IOHandler(void *opaque);
|
||||||
|
|
||||||
|
struct ThreadPool;
|
||||||
|
struct LinuxAioState;
|
||||||
|
|
||||||
struct AioContext {
|
struct AioContext {
|
||||||
GSource source;
|
GSource source;
|
||||||
|
|
||||||
|
@ -119,6 +122,13 @@ struct AioContext {
|
||||||
/* Thread pool for performing work and receiving completion callbacks */
|
/* Thread pool for performing work and receiving completion callbacks */
|
||||||
struct ThreadPool *thread_pool;
|
struct ThreadPool *thread_pool;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
/* State for native Linux AIO. Uses aio_context_acquire/release for
|
||||||
|
* locking.
|
||||||
|
*/
|
||||||
|
struct LinuxAioState *linux_aio;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TimerLists for calling timers - one per clock type */
|
/* TimerLists for calling timers - one per clock type */
|
||||||
QEMUTimerListGroup tlg;
|
QEMUTimerListGroup tlg;
|
||||||
|
|
||||||
|
@ -335,6 +345,9 @@ GSource *aio_get_g_source(AioContext *ctx);
|
||||||
/* Return the ThreadPool bound to this AioContext */
|
/* Return the ThreadPool bound to this AioContext */
|
||||||
struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
|
struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
|
||||||
|
|
||||||
|
/* Return the LinuxAioState bound to this AioContext */
|
||||||
|
struct LinuxAioState *aio_get_linux_aio(AioContext *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aio_timer_new:
|
* aio_timer_new:
|
||||||
* @ctx: the aio context
|
* @ctx: the aio context
|
||||||
|
@ -439,6 +452,6 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external)
|
||||||
*
|
*
|
||||||
* Initialize the aio context.
|
* Initialize the aio context.
|
||||||
*/
|
*/
|
||||||
void aio_context_setup(AioContext *ctx, Error **errp);
|
void aio_context_setup(AioContext *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1279,6 +1279,11 @@ sub process {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Accept git diff extended headers as valid patches
|
||||||
|
if ($line =~ /^(?:rename|copy) (?:from|to) [\w\/\.\-]+\s*$/) {
|
||||||
|
$is_patch = 1;
|
||||||
|
}
|
||||||
|
|
||||||
#check the patch for a signoff:
|
#check the patch for a signoff:
|
||||||
if ($line =~ /^\s*signed-off-by:/i) {
|
if ($line =~ /^\s*signed-off-by:/i) {
|
||||||
# This is a signoff, if ugly, so do not double report.
|
# This is a signoff, if ugly, so do not double report.
|
||||||
|
|
Loading…
Reference in New Issue