From patchwork Fri Apr 8 16:10:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asias He X-Patchwork-Id: 695191 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p38GBuTJ005228 for ; Fri, 8 Apr 2011 16:11:56 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757484Ab1DHQLy (ORCPT ); Fri, 8 Apr 2011 12:11:54 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:55883 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757406Ab1DHQLy (ORCPT ); Fri, 8 Apr 2011 12:11:54 -0400 Received: by mail-pv0-f174.google.com with SMTP id 12so1285585pvg.19 for ; Fri, 08 Apr 2011 09:11:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=Hz+GdVFaQ7ssivWJ1te+pgyqkVCEpcPPOSgEEFwa4HU=; b=Z4mNqqJQ1jiSsIbbxj7SQiCj1OhJit1cykSKudOWhfvlVQhBke5I9FH8tXSIcmirRV 8Wpy9iziD2YSrvmvQ3ht7397pfjstwbwJhmkznkhrFvU0cj3vxTDK3sRDdef/+jiw0fR mcVQlx6L+9MpBqBz62kJT6b/G2HUEl+RuP9BM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=DuEsbe2xhHu/g/eSUctzypuF52iRJBw9ubKTZrBPMIjqJsZMDOaZPMJGGgIL57wiwR HLTQ6/jO+RFzEs9JMWoBaSSUsq0VHPpfWT80BD+l+V7X7/zJQevQebPwTLKOVRT51KIc kysiyedv0uGrmJnAIZqLsFfPhmQKgJSd779U8= Received: by 10.142.224.11 with SMTP id w11mr1979835wfg.136.1302279113822; Fri, 08 Apr 2011 09:11:53 -0700 (PDT) Received: from localhost.localdomain ([219.224.169.130]) by mx.google.com with ESMTPS id s39sm3812390wfc.16.2011.04.08.09.11.50 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 08 Apr 2011 09:11:52 -0700 (PDT) From: Asias He To: Pekka Enberg , Cyrill Gorcunov , Ingo Molnar Cc: kvm@vger.kernel.org, Asias He Subject: [PATCH 5/5] kvm tools: use virt_queue__get_iov to simpify virtio blk io handle logic Date: Sat, 9 Apr 2011 00:10:07 +0800 Message-Id: <1302279007-15710-5-git-send-email-asias.hejun@gmail.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1302279007-15710-1-git-send-email-asias.hejun@gmail.com> References: <1302279007-15710-1-git-send-email-asias.hejun@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 08 Apr 2011 16:11:56 +0000 (UTC) This really makes my life much easier! Signed-off-by: Asias He --- tools/kvm/virtio-blk.c | 109 ++++++++++++++--------------------------------- 1 files changed, 33 insertions(+), 76 deletions(-) diff --git a/tools/kvm/virtio-blk.c b/tools/kvm/virtio-blk.c index 8351e7a..34eb3f7 100644 --- a/tools/kvm/virtio-blk.c +++ b/tools/kvm/virtio-blk.c @@ -30,7 +30,7 @@ struct blk_device { /* virtio queue */ uint16_t queue_selector; - struct virt_queue virt_queues[NUM_VIRT_QUEUES]; + struct virt_queue vqs[NUM_VIRT_QUEUES]; }; #define DISK_SEG_MAX 126 @@ -73,7 +73,7 @@ static bool virtio_blk_pci_io_in(struct kvm *self, uint16_t port, void *data, in case VIRTIO_PCI_GUEST_FEATURES: return false; case VIRTIO_PCI_QUEUE_PFN: - ioport__write32(data, blk_device.virt_queues[blk_device.queue_selector].pfn); + ioport__write32(data, blk_device.vqs[blk_device.queue_selector].pfn); break; case VIRTIO_PCI_QUEUE_NUM: ioport__write16(data, VIRTIO_BLK_QUEUE_SIZE); @@ -98,66 +98,29 @@ static bool virtio_blk_pci_io_in(struct kvm *self, uint16_t port, void *data, in return true; } -static bool virtio_blk_request(struct kvm *self, struct virt_queue *queue) +static bool virtio_blk_do_io_request(struct kvm *self, struct virt_queue *queue) { + + struct iovec iov[VIRTIO_BLK_QUEUE_SIZE]; struct virtio_blk_outhdr *req; - uint16_t desc_block_last; - struct vring_desc *desc; - uint16_t desc_status; - uint16_t desc_block; - uint32_t block_len; - uint32_t block_cnt; - uint16_t desc_hdr; + uint32_t block_len, block_cnt; + uint16_t out, in, head; + int err,err_cnt, i; uint8_t *status; void *block; - int err; - int err_cnt; - - /* header */ - desc_hdr = virt_queue__pop(queue); - - if (desc_hdr >= queue->vring.num) { - warning("fatal I/O error"); - return false; - } - desc = virt_queue__get_desc(queue, desc_hdr); - assert(!(desc->flags & VRING_DESC_F_INDIRECT)); + head = virt_queue__get_iov(queue, iov, &out, &in, self); - req = guest_flat_to_host(self, desc->addr); - - /* status */ - desc_status = desc_hdr; - - do { - desc_block_last = desc_status; - desc_status = virt_queue__get_desc(queue, desc_status)->next; - - if (desc_status >= queue->vring.num) { - warning("fatal I/O error"); - return false; - } - - desc = virt_queue__get_desc(queue, desc_status); - assert(!(desc->flags & VRING_DESC_F_INDIRECT)); - - } while (desc->flags & VRING_DESC_F_NEXT); - - status = guest_flat_to_host(self, desc->addr); + /* head */ + req = iov[0].iov_base; /* block */ - desc_block = desc_hdr; - block_cnt = 0; - err_cnt = 0; + block_cnt = 0; + err_cnt = 0; - do { - desc_block = virt_queue__get_desc(queue, desc_block)->next; - - desc = virt_queue__get_desc(queue, desc_block); - assert(!(desc->flags & VRING_DESC_F_INDIRECT)); - - block = guest_flat_to_host(self, desc->addr); - block_len = desc->len; + for (i = 1; i < out + in - 1; i++) { + block = iov[i].iov_base; + block_len = iov[i].iov_len; switch (req->type) { case VIRTIO_BLK_T_IN: @@ -176,24 +139,28 @@ static bool virtio_blk_request(struct kvm *self, struct virt_queue *queue) req->sector += block_len >> SECTOR_SHIFT; block_cnt += block_len; + } - if (desc_block == desc_block_last) - break; - - if (desc_block >= queue->vring.num) { - warning("fatal I/O error"); - return false; - } - - } while (true); - + /* status */ + status = iov[out + in - 1].iov_base; *status = err_cnt ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK; - virt_queue__set_used_elem(queue, desc_hdr, block_cnt); + virt_queue__set_used_elem(queue, head, block_cnt); return true; } +static void virtio_blk_handle_callback(struct kvm *self, uint16_t queue_index) +{ + struct virt_queue *vq; + + vq = &blk_device.vqs[queue_index]; + while (virt_queue__available(vq)) { + virtio_blk_do_io_request(self, vq); + } + kvm__irq_line(self, VIRTIO_BLK_IRQ, 1); + +} static bool virtio_blk_pci_io_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) { unsigned long offset; @@ -208,7 +175,7 @@ static bool virtio_blk_pci_io_out(struct kvm *self, uint16_t port, void *data, i struct virt_queue *queue; void *p; - queue = &blk_device.virt_queues[blk_device.queue_selector]; + queue = &blk_device.vqs[blk_device.queue_selector]; queue->pfn = ioport__read32(data); @@ -222,19 +189,9 @@ static bool virtio_blk_pci_io_out(struct kvm *self, uint16_t port, void *data, i blk_device.queue_selector = ioport__read16(data); break; case VIRTIO_PCI_QUEUE_NOTIFY: { - struct virt_queue *queue; uint16_t queue_index; - queue_index = ioport__read16(data); - - queue = &blk_device.virt_queues[queue_index]; - - while (queue->vring.avail->idx != queue->last_avail_idx) { - if (!virtio_blk_request(self, queue)) - return false; - } - kvm__irq_line(self, VIRTIO_BLK_IRQ, 1); - + virtio_blk_handle_callback(self, queue_index); break; } case VIRTIO_PCI_STATUS: