From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=58372 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OvFIJ-0005pg-6r for qemu-devel@nongnu.org; Mon, 13 Sep 2010 16:06:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OvFIH-00050w-SX for qemu-devel@nongnu.org; Mon, 13 Sep 2010 16:06:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50873) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OvFIH-00050q-M8 for qemu-devel@nongnu.org; Mon, 13 Sep 2010 16:06:25 -0400 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8DK6PI6026826 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 13 Sep 2010 16:06:25 -0400 From: Kevin Wolf Date: Mon, 13 Sep 2010 22:06:33 +0200 Message-Id: <1284408393-31027-4-git-send-email-kwolf@redhat.com> In-Reply-To: <1284408393-31027-1-git-send-email-kwolf@redhat.com> References: <1284408393-31027-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 3/3] qcow2: Avoid bounce buffers for AIO write requests List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com 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 --- block/qcow2.c | 41 ++++++++++++++++++----------------------- 1 files changed, 18 insertions(+), 23 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 39d989a..fcef0d5 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -332,15 +332,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; @@ -531,14 +528,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; @@ -590,7 +580,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; @@ -606,7 +595,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 */ @@ -637,20 +626,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, @@ -668,9 +664,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