[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 17/20] qcow2: Avoid bounce buffers for AIO write req
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 17/20] qcow2: Avoid bounce buffers for AIO write requests |
Date: |
Tue, 21 Sep 2010 17:21:59 +0200 |
qcow2 used to use bounce buffers for any AIO requests. This does not only imply
unnecessary copying, but also unbounded allocations which should be avoided.
This patch removes bounce buffers from the normal AIO write path. Encrypted
images continue to use a bounce buffer, however with constant size.
Signed-off-by: Kevin Wolf <address@hidden>
---
block/qcow2.c | 41 ++++++++++++++++++-----------------------
1 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 4a688b4..ee3481b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -331,15 +331,12 @@ typedef struct QCowAIOCB {
BlockDriverAIOCB common;
int64_t sector_num;
QEMUIOVector *qiov;
- uint8_t *buf;
- void *orig_buf;
int remaining_sectors;
int cur_nr_sectors; /* number of sectors in current iteration */
uint64_t bytes_done;
uint64_t cluster_offset;
uint8_t *cluster_data;
BlockDriverAIOCB *hd_aiocb;
- struct iovec hd_iov;
QEMUIOVector hd_qiov;
QEMUBH *bh;
QCowL2Meta l2meta;
@@ -530,14 +527,7 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
acb->sector_num = sector_num;
acb->qiov = qiov;
- if (!is_write) {
- qemu_iovec_init(&acb->hd_qiov, qiov->niov);
- } else if (qiov->niov == 1) {
- acb->buf = (uint8_t *)qiov->iov->iov_base;
- } else {
- acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
- qemu_iovec_to_buffer(qiov, acb->buf);
- }
+ qemu_iovec_init(&acb->hd_qiov, qiov->niov);
acb->bytes_done = 0;
acb->remaining_sectors = nb_sectors;
@@ -589,7 +579,6 @@ static void qcow_aio_write_cb(void *opaque, int ret)
BlockDriverState *bs = acb->common.bs;
BDRVQcowState *s = bs->opaque;
int index_in_cluster;
- const uint8_t *src_buf;
int n_end;
acb->hd_aiocb = NULL;
@@ -605,7 +594,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
acb->remaining_sectors -= acb->cur_nr_sectors;
acb->sector_num += acb->cur_nr_sectors;
- acb->buf += acb->cur_nr_sectors * 512;
+ acb->bytes_done += acb->cur_nr_sectors * 512;
if (acb->remaining_sectors == 0) {
/* request completed */
@@ -636,20 +625,27 @@ static void qcow_aio_write_cb(void *opaque, int ret)
assert((acb->cluster_offset & 511) == 0);
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+ acb->cur_nr_sectors * 512);
+
if (s->crypt_method) {
if (!acb->cluster_data) {
acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
s->cluster_size);
}
- qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
- acb->cur_nr_sectors, 1, &s->aes_encrypt_key);
- src_buf = acb->cluster_data;
- } else {
- src_buf = acb->buf;
+
+ assert(acb->hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+ qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
+
+ qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
+ acb->cluster_data, acb->cur_nr_sectors, 1, &s->aes_encrypt_key);
+
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+ acb->cur_nr_sectors * 512);
}
- acb->hd_iov.iov_base = (void *)src_buf;
- acb->hd_iov.iov_len = acb->cur_nr_sectors * 512;
- qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
acb->hd_aiocb = bdrv_aio_writev(bs->file,
(acb->cluster_offset >> 9) +
index_in_cluster,
@@ -667,9 +663,8 @@ fail:
QLIST_REMOVE(&acb->l2meta, next_in_flight);
}
done:
- if (acb->qiov->niov > 1)
- qemu_vfree(acb->orig_buf);
acb->common.cb(acb->common.opaque, ret);
+ qemu_iovec_destroy(&acb->hd_qiov);
qemu_aio_release(acb);
}
--
1.7.2.2
- [Qemu-devel] [PATCH 07/20] nbd: correctly manage default port, (continued)
- [Qemu-devel] [PATCH 07/20] nbd: correctly manage default port, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 08/20] qcow2: Move sync out of write_refcount_block_entries, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 16/20] qcow2: Avoid bounce buffers for AIO read requests, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 14/20] ide: propagate the required alignment, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 15/20] cutils: qemu_iovec_copy and qemu_iovec_memset, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 12/20] virtio-blk: propagate the required alignment, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 09/20] qcow2: Move sync out of update_refcount, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 18/20] scsi-generic: add missing reset handler, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 06/20] Improve qemu-nbd performance by 4400 %, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 19/20] scsi_bus: fix length and xfer_mode for RESERVE and RELEASE commands, Kevin Wolf, 2010/09/21
- [Qemu-devel] [PATCH 17/20] qcow2: Avoid bounce buffers for AIO write requests,
Kevin Wolf <=
- [Qemu-devel] [PATCH 20/20] blkverify: Add block driver for verifying I/O, Kevin Wolf, 2010/09/21
- Re: [Qemu-devel] [PULL 00/20] Block patches, Anthony Liguori, 2010/09/21