Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-reques…
Browse files Browse the repository at this point in the history
…t' into staging

Block pull request

# gpg: Signature made Mon 07 Jul 2014 13:27:20 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request:
  qmp: show QOM properties in device-list-properties
  dataplane: submit I/O as a batch
  linux-aio: implement io plug, unplug and flush io queue
  block: block: introduce APIs for submitting IO as a batch
  ahci: map memory via device's address space instead of address_space_memory
  raw-posix: Fix raw_getlength() to always return -errno on error
  qemu-iotests: Disable Quorum testing in 041 when Quorum is not builtin
  ahci.c: mask unused flags when reading size PRDT DBC
  MAINTAINERS: add Stefan Hajnoczi to IDE maintainers
  mirror: Fix qiov size for short requests
  Fix nocow typos in manpage

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jul 7, 2014
2 parents f811d47 + f4eb32b commit 9540d1f
Show file tree
Hide file tree
Showing 16 changed files with 356 additions and 53 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Expand Up @@ -563,6 +563,7 @@ Devices
-------
IDE
M: Kevin Wolf <kwolf@redhat.com>
M: Stefan Hajnoczi <stefanha@redhat.com>
S: Odd Fixes
F: include/hw/ide.h
F: hw/ide/
Expand Down
31 changes: 31 additions & 0 deletions block.c
Expand Up @@ -1905,6 +1905,7 @@ void bdrv_drain_all(void)
bool bs_busy;

aio_context_acquire(aio_context);
bdrv_flush_io_queue(bs);
bdrv_start_throttled_reqs(bs);
bs_busy = bdrv_requests_pending(bs);
bs_busy |= aio_poll(aio_context, bs_busy);
Expand Down Expand Up @@ -5782,3 +5783,33 @@ BlockDriverState *check_to_replace_node(const char *node_name, Error **errp)

return to_replace_bs;
}

void bdrv_io_plug(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
if (drv && drv->bdrv_io_plug) {
drv->bdrv_io_plug(bs);
} else if (bs->file) {
bdrv_io_plug(bs->file);
}
}

void bdrv_io_unplug(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
if (drv && drv->bdrv_io_unplug) {
drv->bdrv_io_unplug(bs);
} else if (bs->file) {
bdrv_io_unplug(bs->file);
}
}

void bdrv_flush_io_queue(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
if (drv && drv->bdrv_flush_io_queue) {
drv->bdrv_flush_io_queue(bs);
} else if (bs->file) {
bdrv_flush_io_queue(bs->file);
}
}
96 changes: 94 additions & 2 deletions block/linux-aio.c
Expand Up @@ -25,6 +25,8 @@
*/
#define MAX_EVENTS 128

#define MAX_QUEUED_IO 128

struct qemu_laiocb {
BlockDriverAIOCB common;
struct qemu_laio_state *ctx;
Expand All @@ -36,9 +38,19 @@ struct qemu_laiocb {
QLIST_ENTRY(qemu_laiocb) node;
};

typedef struct {
struct iocb *iocbs[MAX_QUEUED_IO];
int plugged;
unsigned int size;
unsigned int idx;
} LaioQueue;

struct qemu_laio_state {
io_context_t ctx;
EventNotifier e;

/* io queue for submit at batch */
LaioQueue io_q;
};

static inline ssize_t io_event_ret(struct io_event *ev)
Expand Down Expand Up @@ -135,6 +147,79 @@ static const AIOCBInfo laio_aiocb_info = {
.cancel = laio_cancel,
};

static void ioq_init(LaioQueue *io_q)
{
io_q->size = MAX_QUEUED_IO;
io_q->idx = 0;
io_q->plugged = 0;
}

static int ioq_submit(struct qemu_laio_state *s)
{
int ret, i = 0;
int len = s->io_q.idx;

do {
ret = io_submit(s->ctx, len, s->io_q.iocbs);
} while (i++ < 3 && ret == -EAGAIN);

/* empty io queue */
s->io_q.idx = 0;

if (ret < 0) {
i = 0;
} else {
i = ret;
}

for (; i < len; i++) {
struct qemu_laiocb *laiocb =
container_of(s->io_q.iocbs[i], struct qemu_laiocb, iocb);

laiocb->ret = (ret < 0) ? ret : -EIO;
qemu_laio_process_completion(s, laiocb);
}
return ret;
}

static void ioq_enqueue(struct qemu_laio_state *s, struct iocb *iocb)
{
unsigned int idx = s->io_q.idx;

s->io_q.iocbs[idx++] = iocb;
s->io_q.idx = idx;

/* submit immediately if queue is full */
if (idx == s->io_q.size) {
ioq_submit(s);
}
}

void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
{
struct qemu_laio_state *s = aio_ctx;

s->io_q.plugged++;
}

int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
{
struct qemu_laio_state *s = aio_ctx;
int ret = 0;

assert(s->io_q.plugged > 0 || !unplug);

if (unplug && --s->io_q.plugged > 0) {
return 0;
}

if (s->io_q.idx > 0) {
ret = ioq_submit(s);
}

return ret;
}

BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque, int type)
Expand Down Expand Up @@ -168,8 +253,13 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
}
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));

if (io_submit(s->ctx, 1, &iocbs) < 0)
goto out_free_aiocb;
if (!s->io_q.plugged) {
if (io_submit(s->ctx, 1, &iocbs) < 0) {
goto out_free_aiocb;
}
} else {
ioq_enqueue(s, iocbs);
}
return &laiocb->common;

out_free_aiocb:
Expand Down Expand Up @@ -204,6 +294,8 @@ void *laio_init(void)
goto out_close_efd;
}

ioq_init(&s->io_q);

return s;

out_close_efd:
Expand Down
4 changes: 3 additions & 1 deletion block/mirror.c
Expand Up @@ -265,9 +265,11 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
next_sector = sector_num;
while (nb_chunks-- > 0) {
MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free);
size_t remaining = (nb_sectors * BDRV_SECTOR_SIZE) - op->qiov.size;

QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next);
s->buf_free_count--;
qemu_iovec_add(&op->qiov, buf, s->granularity);
qemu_iovec_add(&op->qiov, buf, MIN(s->granularity, remaining));

/* Advance the HBitmapIter in parallel, so that we do not examine
* the same sector twice.
Expand Down
2 changes: 2 additions & 0 deletions block/raw-aio.h
Expand Up @@ -40,6 +40,8 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
BlockDriverCompletionFunc *cb, void *opaque, int type);
void laio_detach_aio_context(void *s, AioContext *old_context);
void laio_attach_aio_context(void *s, AioContext *new_context);
void laio_io_plug(BlockDriverState *bs, void *aio_ctx);
int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug);
#endif

#ifdef _WIN32
Expand Down
73 changes: 67 additions & 6 deletions block/raw-posix.c
Expand Up @@ -1057,6 +1057,36 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
cb, opaque, type);
}

static void raw_aio_plug(BlockDriverState *bs)
{
#ifdef CONFIG_LINUX_AIO
BDRVRawState *s = bs->opaque;
if (s->use_aio) {
laio_io_plug(bs, s->aio_ctx);
}
#endif
}

static void raw_aio_unplug(BlockDriverState *bs)
{
#ifdef CONFIG_LINUX_AIO
BDRVRawState *s = bs->opaque;
if (s->use_aio) {
laio_io_unplug(bs, s->aio_ctx, true);
}
#endif
}

static void raw_aio_flush_io_queue(BlockDriverState *bs)
{
#ifdef CONFIG_LINUX_AIO
BDRVRawState *s = bs->opaque;
if (s->use_aio) {
laio_io_unplug(bs, s->aio_ctx, false);
}
#endif
}

static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
Expand Down Expand Up @@ -1133,12 +1163,12 @@ static int64_t raw_getlength(BlockDriverState *bs)
struct stat st;

if (fstat(fd, &st))
return -1;
return -errno;
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
struct disklabel dl;

if (ioctl(fd, DIOCGDINFO, &dl))
return -1;
return -errno;
return (uint64_t)dl.d_secsize *
dl.d_partitions[DISKPART(st.st_rdev)].p_size;
} else
Expand All @@ -1152,7 +1182,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
struct stat st;

if (fstat(fd, &st))
return -1;
return -errno;
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
struct dkwedge_info dkw;

Expand All @@ -1162,7 +1192,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
struct disklabel dl;

if (ioctl(fd, DIOCGDINFO, &dl))
return -1;
return -errno;
return (uint64_t)dl.d_secsize *
dl.d_partitions[DISKPART(st.st_rdev)].p_size;
}
Expand All @@ -1175,6 +1205,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
BDRVRawState *s = bs->opaque;
struct dk_minfo minfo;
int ret;
int64_t size;

ret = fd_open(bs);
if (ret < 0) {
Expand All @@ -1193,7 +1224,11 @@ static int64_t raw_getlength(BlockDriverState *bs)
* There are reports that lseek on some devices fails, but
* irc discussion said that contingency on contingency was overkill.
*/
return lseek(s->fd, 0, SEEK_END);
size = lseek(s->fd, 0, SEEK_END);
if (size < 0) {
return -errno;
}
return size;
}
#elif defined(CONFIG_BSD)
static int64_t raw_getlength(BlockDriverState *bs)
Expand Down Expand Up @@ -1231,6 +1266,9 @@ static int64_t raw_getlength(BlockDriverState *bs)
size = LLONG_MAX;
#else
size = lseek(fd, 0LL, SEEK_END);
if (size < 0) {
return -errno;
}
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
switch(s->type) {
Expand All @@ -1247,6 +1285,9 @@ static int64_t raw_getlength(BlockDriverState *bs)
#endif
} else {
size = lseek(fd, 0, SEEK_END);
if (size < 0) {
return -errno;
}
}
return size;
}
Expand All @@ -1255,13 +1296,18 @@ static int64_t raw_getlength(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
int ret;
int64_t size;

ret = fd_open(bs);
if (ret < 0) {
return ret;
}

return lseek(s->fd, 0, SEEK_END);
size = lseek(s->fd, 0, SEEK_END);
if (size < 0) {
return -errno;
}
return size;
}
#endif

Expand Down Expand Up @@ -1528,6 +1574,9 @@ static BlockDriver bdrv_file = {
.bdrv_aio_flush = raw_aio_flush,
.bdrv_aio_discard = raw_aio_discard,
.bdrv_refresh_limits = raw_refresh_limits,
.bdrv_io_plug = raw_aio_plug,
.bdrv_io_unplug = raw_aio_unplug,
.bdrv_flush_io_queue = raw_aio_flush_io_queue,

.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
Expand Down Expand Up @@ -1927,6 +1976,9 @@ static BlockDriver bdrv_host_device = {
.bdrv_aio_flush = raw_aio_flush,
.bdrv_aio_discard = hdev_aio_discard,
.bdrv_refresh_limits = raw_refresh_limits,
.bdrv_io_plug = raw_aio_plug,
.bdrv_io_unplug = raw_aio_unplug,
.bdrv_flush_io_queue = raw_aio_flush_io_queue,

.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
Expand Down Expand Up @@ -2072,6 +2124,9 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_refresh_limits = raw_refresh_limits,
.bdrv_io_plug = raw_aio_plug,
.bdrv_io_unplug = raw_aio_unplug,
.bdrv_flush_io_queue = raw_aio_flush_io_queue,

.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
Expand Down Expand Up @@ -2200,6 +2255,9 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_refresh_limits = raw_refresh_limits,
.bdrv_io_plug = raw_aio_plug,
.bdrv_io_unplug = raw_aio_unplug,
.bdrv_flush_io_queue = raw_aio_flush_io_queue,

.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
Expand Down Expand Up @@ -2334,6 +2392,9 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_refresh_limits = raw_refresh_limits,
.bdrv_io_plug = raw_aio_plug,
.bdrv_io_unplug = raw_aio_unplug,
.bdrv_flush_io_queue = raw_aio_flush_io_queue,

.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
Expand Down

0 comments on commit 9540d1f

Please sign in to comment.