From patchwork Sat Apr 9 10:34:57 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pekka Enberg X-Patchwork-Id: 695781 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 p39AZ2kj026690 for ; Sat, 9 Apr 2011 10:35:02 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754112Ab1DIKe7 (ORCPT ); Sat, 9 Apr 2011 06:34:59 -0400 Received: from filtteri6.pp.htv.fi ([213.243.153.189]:56222 "EHLO filtteri6.pp.htv.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754030Ab1DIKe7 (ORCPT ); Sat, 9 Apr 2011 06:34:59 -0400 Received: from localhost (localhost [127.0.0.1]) by filtteri6.pp.htv.fi (Postfix) with ESMTP id 349CB62A005; Sat, 9 Apr 2011 13:34:58 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at pp.htv.fi Received: from smtp4.welho.com ([213.243.153.38]) by localhost (filtteri6.pp.htv.fi [213.243.153.189]) (amavisd-new, port 10024) with ESMTP id SOmwZTSRdO+z; Sat, 9 Apr 2011 13:34:57 +0300 (EEST) Received: from localhost.localdomain (cs181148025.pp.htv.fi [82.181.148.25]) by smtp4.welho.com (Postfix) with ESMTP id B9D9E5BC010; Sat, 9 Apr 2011 13:34:57 +0300 (EEST) From: Pekka Enberg To: kvm@vger.kernel.org Cc: Pekka Enberg , Asias He , Cyrill Gorcunov , Ingo Molnar Subject: [PATCH] kvm tools: Make virtio block device code thread-safe Date: Sat, 9 Apr 2011 13:34:57 +0300 Message-Id: <1302345297-31594-1-git-send-email-penberg@kernel.org> X-Mailer: git-send-email 1.7.0.4 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]); Sat, 09 Apr 2011 10:35:03 +0000 (UTC) In preparation for threaded execution, make the virtio block device code safe by introducing a per-device mutex. Cc: Asias He Cc: Cyrill Gorcunov Cc: Ingo Molnar Signed-off-by: Pekka Enberg --- tools/kvm/virtio-blk.c | 41 +++++++++++++++++++++++++++++++++-------- 1 files changed, 33 insertions(+), 8 deletions(-) diff --git a/tools/kvm/virtio-blk.c b/tools/kvm/virtio-blk.c index 874e92e..8f1c684 100644 --- a/tools/kvm/virtio-blk.c +++ b/tools/kvm/virtio-blk.c @@ -11,8 +11,9 @@ #include #include + #include -#include +#include #define VIRTIO_BLK_IRQ 14 @@ -21,6 +22,8 @@ #define VIRTIO_BLK_QUEUE_SIZE 128 struct blk_device { + pthread_mutex_t mutex; + struct virtio_blk_config blk_config; uint32_t host_features; uint32_t guest_features; @@ -36,6 +39,8 @@ struct blk_device { #define DISK_SEG_MAX 126 static struct blk_device blk_device = { + .mutex = PTHREAD_MUTEX_INITIALIZER, + .blk_config = (struct virtio_blk_config) { /* VIRTIO_BLK_F_SEG_MAX */ .seg_max = DISK_SEG_MAX, @@ -63,6 +68,10 @@ static bool virtio_blk_pci_io_device_specific_in(void *data, unsigned long offse static bool virtio_blk_pci_io_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) { unsigned long offset; + bool ret = true; + + if (pthread_mutex_lock(&blk_device.mutex) < 0) + die("pthread_mutex_lock"); offset = port - IOPORT_VIRTIO_BLK; @@ -71,7 +80,8 @@ static bool virtio_blk_pci_io_in(struct kvm *self, uint16_t port, void *data, in ioport__write32(data, blk_device.host_features); break; case VIRTIO_PCI_GUEST_FEATURES: - return false; + ret = false; + goto out_unlock; case VIRTIO_PCI_QUEUE_PFN: ioport__write32(data, blk_device.vqs[blk_device.queue_selector].pfn); break; @@ -80,7 +90,8 @@ static bool virtio_blk_pci_io_in(struct kvm *self, uint16_t port, void *data, in break; case VIRTIO_PCI_QUEUE_SEL: case VIRTIO_PCI_QUEUE_NOTIFY: - return false; + ret = false; + goto out_unlock; case VIRTIO_PCI_STATUS: ioport__write8(data, blk_device.status); break; @@ -92,15 +103,19 @@ static bool virtio_blk_pci_io_in(struct kvm *self, uint16_t port, void *data, in ioport__write16(data, blk_device.config_vector); break; default: - return virtio_blk_pci_io_device_specific_in(data, offset, size, count); + ret = virtio_blk_pci_io_device_specific_in(data, offset, size, count); + goto out_unlock; }; - return true; +out_unlock: + if (pthread_mutex_unlock(&blk_device.mutex) < 0) + die("pthread_mutex_unlock"); + + return ret; } 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; uint32_t block_len, block_cnt; @@ -159,9 +174,14 @@ static void virtio_blk_handle_callback(struct kvm *self, uint16_t queue_index) 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; + bool ret = true; + + if (pthread_mutex_lock(&blk_device.mutex) < 0) + die("pthread_mutex_lock"); offset = port - IOPORT_VIRTIO_BLK; @@ -201,10 +221,15 @@ static bool virtio_blk_pci_io_out(struct kvm *self, uint16_t port, void *data, i case VIRTIO_MSI_QUEUE_VECTOR: break; default: - return false; + ret = false; + goto out_unlock; }; - return true; +out_unlock: + if (pthread_mutex_unlock(&blk_device.mutex) < 0) + die("pthread_mutex_unlock"); + + return ret; } static struct ioport_operations virtio_blk_io_ops = {