mirror of https://github.com/xemu-project/xemu.git
linux-aio: add `dev_max_batch` parameter to laio_co_submit()
This new parameter can be used by block devices to limit the Linux AIO batch size more than the limit set by the AIO context. file-posix backend supports this, passing its `aio-max-batch` option previously added. Add an helper function to calculate the maximum batch size. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Message-Id: <20211026162346.253081-3-sgarzare@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
684960d462
commit
512da21101
|
@ -2066,7 +2066,8 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
|
||||||
} else if (s->use_linux_aio) {
|
} else if (s->use_linux_aio) {
|
||||||
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||||
assert(qiov->size == bytes);
|
assert(qiov->size == bytes);
|
||||||
return laio_co_submit(bs, aio, s->fd, offset, qiov, type);
|
return laio_co_submit(bs, aio, s->fd, offset, qiov, type,
|
||||||
|
s->aio_max_batch);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,6 +334,23 @@ static void ioq_submit(LinuxAioState *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t laio_max_batch(LinuxAioState *s, uint64_t dev_max_batch)
|
||||||
|
{
|
||||||
|
uint64_t max_batch = s->aio_context->aio_max_batch ?: DEFAULT_MAX_BATCH;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AIO context can be shared between multiple block devices, so
|
||||||
|
* `dev_max_batch` allows reducing the batch size for latency-sensitive
|
||||||
|
* devices.
|
||||||
|
*/
|
||||||
|
max_batch = MIN_NON_ZERO(dev_max_batch, max_batch);
|
||||||
|
|
||||||
|
/* limit the batch with the number of available events */
|
||||||
|
max_batch = MIN_NON_ZERO(MAX_EVENTS - s->io_q.in_flight, max_batch);
|
||||||
|
|
||||||
|
return max_batch;
|
||||||
|
}
|
||||||
|
|
||||||
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s)
|
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s)
|
||||||
{
|
{
|
||||||
s->io_q.plugged++;
|
s->io_q.plugged++;
|
||||||
|
@ -349,15 +366,11 @@ void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||||
int type)
|
int type, uint64_t dev_max_batch)
|
||||||
{
|
{
|
||||||
LinuxAioState *s = laiocb->ctx;
|
LinuxAioState *s = laiocb->ctx;
|
||||||
struct iocb *iocbs = &laiocb->iocb;
|
struct iocb *iocbs = &laiocb->iocb;
|
||||||
QEMUIOVector *qiov = laiocb->qiov;
|
QEMUIOVector *qiov = laiocb->qiov;
|
||||||
int64_t max_batch = s->aio_context->aio_max_batch ?: DEFAULT_MAX_BATCH;
|
|
||||||
|
|
||||||
/* limit the batch with the number of available events */
|
|
||||||
max_batch = MIN_NON_ZERO(MAX_EVENTS - s->io_q.in_flight, max_batch);
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QEMU_AIO_WRITE:
|
case QEMU_AIO_WRITE:
|
||||||
|
@ -378,7 +391,7 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||||
s->io_q.in_queue++;
|
s->io_q.in_queue++;
|
||||||
if (!s->io_q.blocked &&
|
if (!s->io_q.blocked &&
|
||||||
(!s->io_q.plugged ||
|
(!s->io_q.plugged ||
|
||||||
s->io_q.in_queue >= max_batch)) {
|
s->io_q.in_queue >= laio_max_batch(s, dev_max_batch))) {
|
||||||
ioq_submit(s);
|
ioq_submit(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +399,8 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
||||||
uint64_t offset, QEMUIOVector *qiov, int type)
|
uint64_t offset, QEMUIOVector *qiov, int type,
|
||||||
|
uint64_t dev_max_batch)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct qemu_laiocb laiocb = {
|
struct qemu_laiocb laiocb = {
|
||||||
|
@ -398,7 +412,7 @@ int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
||||||
.qiov = qiov,
|
.qiov = qiov,
|
||||||
};
|
};
|
||||||
|
|
||||||
ret = laio_do_submit(fd, &laiocb, offset, type);
|
ret = laio_do_submit(fd, &laiocb, offset, type, dev_max_batch);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,8 @@ typedef struct LinuxAioState LinuxAioState;
|
||||||
LinuxAioState *laio_init(Error **errp);
|
LinuxAioState *laio_init(Error **errp);
|
||||||
void laio_cleanup(LinuxAioState *s);
|
void laio_cleanup(LinuxAioState *s);
|
||||||
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
||||||
uint64_t offset, QEMUIOVector *qiov, int type);
|
uint64_t offset, QEMUIOVector *qiov, int type,
|
||||||
|
uint64_t dev_max_batch);
|
||||||
void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context);
|
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);
|
||||||
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s);
|
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s);
|
||||||
|
|
Loading…
Reference in New Issue