From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LjqaB-0003vG-1r for qemu-devel@nongnu.org; Wed, 18 Mar 2009 03:52:59 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Ljqa5-0003rX-VK for qemu-devel@nongnu.org; Wed, 18 Mar 2009 03:52:58 -0400 Received: from [199.232.76.173] (port=47793 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ljqa5-0003rK-J2 for qemu-devel@nongnu.org; Wed, 18 Mar 2009 03:52:53 -0400 Received: from verein.lst.de ([213.95.11.210]:45832) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA1:24) (Exim 4.60) (envelope-from ) id 1Ljqa4-0005Zg-UQ for qemu-devel@nongnu.org; Wed, 18 Mar 2009 03:52:53 -0400 Received: from verein.lst.de (localhost [127.0.0.1]) by verein.lst.de (8.12.3/8.12.3/Debian-7.1) with ESMTP id n2I7qpIF013600 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Wed, 18 Mar 2009 08:52:51 +0100 Received: (from hch@localhost) by verein.lst.de (8.12.3/8.12.3/Debian-6.6) id n2I7qpaF013598 for qemu-devel@nongnu.org; Wed, 18 Mar 2009 08:52:51 +0100 Date: Wed, 18 Mar 2009 08:52:51 +0100 From: Christoph Hellwig Message-ID: <20090318075251.GB13571@lst.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH 2/2] virtio-blk: use generic vectored I/O APIs Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Use the generic bdrv_aio_readv/bdrv_aio_writev APIs instead of linearizing buffers directly. This enables using the future native preadv/pwritev support. Signed-off-by: Christoph Hellwig Index: qemu/hw/virtio-blk.c =================================================================== --- qemu.orig/hw/virtio-blk.c 2009-03-18 08:43:29.433979177 +0100 +++ qemu/hw/virtio-blk.c 2009-03-18 08:46:31.186981074 +0100 @@ -35,8 +35,7 @@ typedef struct VirtIOBlockReq VirtQueueElement elem; struct virtio_blk_inhdr *in; struct virtio_blk_outhdr *out; - size_t size; - uint8_t *buffer; + QEMUIOVector qiov; struct VirtIOBlockReq *next; } VirtIOBlockReq; @@ -45,10 +44,9 @@ static void virtio_blk_req_complete(Virt VirtIOBlock *s = req->dev; req->in->status = status; - virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in)); + virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in)); virtio_notify(&s->vdev, s->vq); - qemu_free(req->buffer); qemu_free(req); } @@ -76,24 +74,7 @@ static void virtio_blk_rw_complete(void { VirtIOBlockReq *req = opaque; - /* Copy read data to the guest */ - if (!ret && !(req->out->type & VIRTIO_BLK_T_OUT)) { - size_t offset = 0; - int i; - - for (i = 0; i < req->elem.in_num - 1; i++) { - size_t len; - - /* Be pretty defensive wrt malicious guests */ - len = MIN(req->elem.in_sg[i].iov_len, - req->size - offset); - - memcpy(req->elem.in_sg[i].iov_base, - req->buffer + offset, - len); - offset += len; - } - } else if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) { + if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) { if (virtio_blk_handle_write_error(req, -ret)) return; } @@ -122,39 +103,16 @@ static VirtIOBlockReq *virtio_blk_get_re return req; } -static int virtio_blk_handle_write(VirtIOBlockReq *req) +static void virtio_blk_handle_write(VirtIOBlockReq *req) { - if (!req->buffer) { - size_t offset = 0; - int i; - - for (i = 1; i < req->elem.out_num; i++) - req->size += req->elem.out_sg[i].iov_len; - - req->buffer = qemu_memalign(512, req->size); - if (req->buffer == NULL) { - qemu_free(req); - return -1; - } - - /* We copy the data from the SG list to avoid splitting up the request. - This helps performance a lot until we can pass full sg lists as AIO - operations */ - for (i = 1; i < req->elem.out_num; i++) { - size_t len; - - len = MIN(req->elem.out_sg[i].iov_len, - req->size - offset); - memcpy(req->buffer + offset, - req->elem.out_sg[i].iov_base, - len); - offset += len; - } - } + bdrv_aio_writev(req->dev->bs, req->out->sector, &req->qiov, + req->qiov.size / 512, virtio_blk_rw_complete, req); +} - bdrv_aio_write(req->dev->bs, req->out->sector, req->buffer, req->size / 512, - virtio_blk_rw_complete, req); - return 0; +static void virtio_blk_handle_read(VirtIOBlockReq *req) +{ + bdrv_aio_readv(req->dev->bs, req->out->sector, &req->qiov, + req->qiov.size / 512, virtio_blk_rw_complete, req); } static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) @@ -163,8 +121,6 @@ static void virtio_blk_handle_output(Vir VirtIOBlockReq *req; while ((req = virtio_blk_get_request(s))) { - int i; - if (req->elem.out_num < 1 || req->elem.in_num < 1) { fprintf(stderr, "virtio-blk missing headers\n"); exit(1); @@ -187,23 +143,13 @@ static void virtio_blk_handle_output(Vir virtio_notify(vdev, vq); qemu_free(req); } else if (req->out->type & VIRTIO_BLK_T_OUT) { - if (virtio_blk_handle_write(req) < 0) - break; + qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1], + req->elem.out_num - 1); + virtio_blk_handle_write(req); } else { - for (i = 0; i < req->elem.in_num - 1; i++) - req->size += req->elem.in_sg[i].iov_len; - - req->buffer = qemu_memalign(512, req->size); - if (req->buffer == NULL) { - qemu_free(req); - break; - } - - bdrv_aio_read(s->bs, req->out->sector, - req->buffer, - req->size / 512, - virtio_blk_rw_complete, - req); + qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0], + req->elem.in_num - 1); + virtio_blk_handle_read(req); } } /*