From patchwork Wed Apr 4 12:53:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894981 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GQvf1Bspz9ryG for ; Wed, 4 Apr 2018 22:56:46 +1000 (AEST) Received: from localhost ([::1]:56243 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hy0-0001Iv-4a for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 08:56:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54227) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hx9-0001De-5A for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hwz-0005XJ-KS for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:44928 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hwz-0005WK-1x for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:41 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A132140201A4; Wed, 4 Apr 2018 12:55:38 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id 68945215CDAF; Wed, 4 Apr 2018 12:55:36 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:53:57 +0800 Message-Id: <1522846444-31725-2-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 04 Apr 2018 12:55:38 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 04 Apr 2018 12:55:38 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 1/8] virtio: feature bit, data structure for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Only minimum definitions from the spec are included for prototype. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 47 +++++++++++++++++++++++--- include/hw/virtio/virtio.h | 12 ++++++- include/standard-headers/linux/virtio_config.h | 2 ++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 006d3d1..9a6bfe7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -39,6 +39,14 @@ typedef struct VRingDesc uint16_t next; } VRingDesc; +typedef struct VRingDescPacked +{ + uint64_t addr; + uint32_t len; + uint16_t id; + uint16_t flags; +} VRingDescPacked; + typedef struct VRingAvail { uint16_t flags; @@ -61,9 +69,18 @@ typedef struct VRingUsed typedef struct VRingMemoryRegionCaches { struct rcu_head rcu; - MemoryRegionCache desc; - MemoryRegionCache avail; - MemoryRegionCache used; + union { + struct { + MemoryRegionCache desc; + MemoryRegionCache avail; + MemoryRegionCache used; + }; + struct { + MemoryRegionCache desc_packed; + MemoryRegionCache driver; + MemoryRegionCache device; + }; + }; } VRingMemoryRegionCaches; typedef struct VRing @@ -77,10 +94,31 @@ typedef struct VRing VRingMemoryRegionCaches *caches; } VRing; +typedef struct VRingPackedDescEvent { + uint16_t desc_event_off:15, + desc_event_wrap:1; + uint16_t desc_event_flags:2; +} VRingPackedDescEvent ; + +typedef struct VRingPacked +{ + unsigned int num; + unsigned int num_default; + unsigned int align; + hwaddr desc; + hwaddr driver; + hwaddr device; + VRingMemoryRegionCaches *caches; +} VRingPacked; + struct VirtQueue { - VRing vring; + union { + struct VRing vring; + struct VRingPacked packed; + }; + uint8_t wrap_counter:1; /* Next head to pop */ uint16_t last_avail_idx; @@ -1220,6 +1258,7 @@ void virtio_reset(void *opaque) vdev->vq[i].vring.num = vdev->vq[i].vring.num_default; vdev->vq[i].inuse = 0; virtio_virtqueue_reset_region_cache(&vdev->vq[i]); + vdev->vq[i].wrap_counter = 1; } } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 098bdaa..563e88e 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -46,6 +46,14 @@ typedef struct VirtQueueElement unsigned int index; unsigned int out_num; unsigned int in_num; + + /* Number of descriptors used by packed ring */ + uint16_t count; + uint8_t wrap_counter:1; + /* FIXME: Length of every used buffer for a descriptor, + move to dynamical allocating due to out/in sgs numbers */ + uint32_t len[VIRTQUEUE_MAX_SIZE]; + hwaddr *in_addr; hwaddr *out_addr; struct iovec *in_sg; @@ -262,7 +270,9 @@ typedef struct VirtIORNGConf VirtIORNGConf; DEFINE_PROP_BIT64("any_layout", _state, _field, \ VIRTIO_F_ANY_LAYOUT, true), \ DEFINE_PROP_BIT64("iommu_platform", _state, _field, \ - VIRTIO_F_IOMMU_PLATFORM, false) + VIRTIO_F_IOMMU_PLATFORM, false), \ + DEFINE_PROP_BIT64("ring_packed", _state, _field, \ + VIRTIO_F_RING_PACKED, true) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h index b777069..6ee5529 100644 --- a/include/standard-headers/linux/virtio_config.h +++ b/include/standard-headers/linux/virtio_config.h @@ -71,4 +71,6 @@ * this is for compatibility with legacy systems. */ #define VIRTIO_F_IOMMU_PLATFORM 33 + +#define VIRTIO_F_RING_PACKED 34 #endif /* _LINUX_VIRTIO_CONFIG_H */ From patchwork Wed Apr 4 12:53:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894983 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GQwH6Fqsz9ryG for ; Wed, 4 Apr 2018 22:57:19 +1000 (AEST) Received: from localhost ([::1]:56255 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hyX-0001mN-Sv for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 08:57:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54180) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hx5-0001AL-Bf for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hx1-0005ZB-6y for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:47 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:44930 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hx0-0005Yk-O8 for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:42 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D7B4F40201A4; Wed, 4 Apr 2018 12:55:41 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2D12E215CDAF; Wed, 4 Apr 2018 12:55:38 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:53:58 +0800 Message-Id: <1522846444-31725-3-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 04 Apr 2018 12:55:41 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 04 Apr 2018 12:55:41 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 2/8] virtio: memory cache for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu A new memory cache is introduced to for packed ring, the code looks pretty duplicated with split(1.0) ring, any refactor idea? Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 9a6bfe7..73a35a4 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -155,13 +155,15 @@ static void virtio_free_region_cache(VRingMemoryRegionCaches *caches) return; } + /* FIX ME: pass in 1.1 device here, reuse 1.0 fields at current */ + address_space_cache_destroy(&caches->desc); address_space_cache_destroy(&caches->avail); address_space_cache_destroy(&caches->used); g_free(caches); } -static void virtio_init_region_cache(VirtIODevice *vdev, int n) +static void virtio_init_region_cache_split(VirtIODevice *vdev, int n) { VirtQueue *vq = &vdev->vq[n]; VRingMemoryRegionCaches *old = vq->vring.caches; @@ -215,6 +217,65 @@ err_desc: g_free(new); } +static void virtio_init_region_cache_packed(VirtIODevice *vdev, int n) +{ + VirtQueue *vq = &vdev->vq[n]; + VRingMemoryRegionCaches *old = vq->vring.caches; + VRingMemoryRegionCaches *new; + hwaddr addr, size; + int64_t len; + + addr = vq->packed.desc; + if (!addr) { + return; + } + new = g_new0(VRingMemoryRegionCaches, 1); + size = virtio_queue_get_desc_size(vdev, n); + len = address_space_cache_init(&new->desc_packed, vdev->dma_as, + addr, size, false); + if (len < size) { + virtio_error(vdev, "Cannot map desc"); + goto err_desc; + } + + size = sizeof(struct VRingPackedDescEvent); + len = address_space_cache_init(&new->driver, vdev->dma_as, + vq->packed.driver, size, true); + if (len < size) { + virtio_error(vdev, "Cannot map driver area"); + goto err_driver; + } + + len = address_space_cache_init(&new->device, vdev->dma_as, + vq->packed.device, size, true); + if (len < size) { + virtio_error(vdev, "Cannot map device area"); + goto err_device; + } + + atomic_rcu_set(&vq->packed.caches, new); + if (old) { + call_rcu(old, virtio_free_region_cache, rcu); + } + return; + +err_device: + address_space_cache_destroy(&new->driver); +err_driver: + address_space_cache_destroy(&new->desc); +err_desc: + g_free(new); +} + +static void virtio_init_region_cache(VirtIODevice *vdev, int n) +{ + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + virtio_init_region_cache_packed(vdev, n); + } else { + virtio_init_region_cache_split(vdev, n); + } +} + /* virt queue functions */ void virtio_queue_update_rings(VirtIODevice *vdev, int n) { @@ -245,10 +306,18 @@ static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc, static VRingMemoryRegionCaches *vring_get_region_caches(struct VirtQueue *vq) { - VRingMemoryRegionCaches *caches = atomic_rcu_read(&vq->vring.caches); + VRingMemoryRegionCaches *caches; + + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + caches = atomic_rcu_read(&vq->packed.caches); + } else { + caches = atomic_rcu_read(&vq->vring.caches); + } + assert(caches != NULL); return caches; } + /* Called within rcu_read_lock(). */ static inline uint16_t vring_avail_flags(VirtQueue *vq) { @@ -2331,7 +2400,11 @@ hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n) hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n) { - return sizeof(VRingDesc) * vdev->vq[n].vring.num; + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + return sizeof(VRingDescPacked) * vdev->vq[n].packed.num; + } else { + return sizeof(VRingDesc) * vdev->vq[n].vring.num; + } } hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n) From patchwork Wed Apr 4 12:53:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894986 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GR2y3xpGz9s1l for ; Wed, 4 Apr 2018 23:03:06 +1000 (AEST) Received: from localhost ([::1]:56464 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3i48-0006nD-Je for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 09:03:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54247) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hxA-0001Ey-Rm for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hx4-0005bD-BE for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:52 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50830 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hx3-0005a8-Is for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:45 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 91337814DF4C; Wed, 4 Apr 2018 12:55:44 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id 615AB215CDAF; Wed, 4 Apr 2018 12:55:42 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:53:59 +0800 Message-Id: <1522846444-31725-4-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 04 Apr 2018 12:55:44 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 04 Apr 2018 12:55:44 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 3/8] virtio: add empty check for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu helper for ring empty check. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 73a35a4..478df3d 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -24,6 +24,9 @@ #include "hw/virtio/virtio-access.h" #include "sysemu/dma.h" +#define AVAIL_DESC_PACKED(b) ((b) << 7) +#define USED_DESC_PACKED(b) ((b) << 15) + /* * The alignment to use between consumer and producer parts of vring. * x86 pagesize again. This is the default, used by transports like PCI @@ -446,10 +449,27 @@ int virtio_queue_ready(VirtQueue *vq) return vq->vring.avail != 0; } +static void vring_desc_read_packed(VirtIODevice *vdev, VRingDescPacked *desc, + MemoryRegionCache *cache, int i) +{ + address_space_read_cached(cache, i * sizeof(VRingDescPacked), + desc, sizeof(VRingDescPacked)); + virtio_tswap64s(vdev, &desc->addr); + virtio_tswap32s(vdev, &desc->len); + virtio_tswap16s(vdev, &desc->id); + virtio_tswap16s(vdev, &desc->flags); +} + +static inline bool is_desc_avail(struct VRingDescPacked* desc) +{ + return (!!(desc->flags & AVAIL_DESC_PACKED(1)) != + !!(desc->flags & USED_DESC_PACKED(1))); +} + /* Fetch avail_idx from VQ memory only when we really need to know if * guest has added some buffers. * Called within rcu_read_lock(). */ -static int virtio_queue_empty_rcu(VirtQueue *vq) +static int virtio_queue_empty_split_rcu(VirtQueue *vq) { if (unlikely(!vq->vring.avail)) { return 1; @@ -462,7 +482,7 @@ static int virtio_queue_empty_rcu(VirtQueue *vq) return vring_avail_idx(vq) == vq->last_avail_idx; } -int virtio_queue_empty(VirtQueue *vq) +static int virtio_queue_empty_split(VirtQueue *vq) { bool empty; @@ -480,6 +500,42 @@ int virtio_queue_empty(VirtQueue *vq) return empty; } +static int virtio_queue_empty_packed_rcu(VirtQueue *vq) +{ + struct VRingDescPacked desc; + VRingMemoryRegionCaches *cache; + + if (unlikely(!vq->packed.desc)) { + return 1; + } + + cache = vring_get_region_caches(vq); + vring_desc_read_packed(vq->vdev, &desc, &cache->desc_packed, vq->last_avail_idx); + + /* Make sure we see the updated flag */ + smp_mb(); + return !is_desc_avail(&desc); +} + +static int virtio_queue_empty_packed(VirtQueue *vq) +{ + bool empty; + + rcu_read_lock(); + empty = virtio_queue_empty_packed_rcu(vq); + rcu_read_unlock(); + return empty; +} + +int virtio_queue_empty(VirtQueue *vq) +{ + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + return virtio_queue_empty_packed(vq); + } else { + return virtio_queue_empty_split(vq); + } +} + static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { @@ -951,7 +1007,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) return NULL; } rcu_read_lock(); - if (virtio_queue_empty_rcu(vq)) { + if (virtio_queue_empty_split_rcu(vq)) { goto done; } /* Needed after virtio_queue_empty(), see comment in From patchwork Wed Apr 4 12:54:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894985 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GQzW3hq6z9s0p for ; Wed, 4 Apr 2018 23:00:07 +1000 (AEST) Received: from localhost ([::1]:56359 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3i1F-0004Z2-He for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 09:00:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54226) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hx9-0001Dc-4k for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hx6-0005ck-PN for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:51 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:44934 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hx6-0005c1-7O for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:48 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4CE4940201A4; Wed, 4 Apr 2018 12:55:47 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1EDBB215CDAF; Wed, 4 Apr 2018 12:55:44 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:54:00 +0800 Message-Id: <1522846444-31725-5-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 04 Apr 2018 12:55:47 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 04 Apr 2018 12:55:47 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 4/8] virtio: add detach element for packed ring(1.1) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu helper for packed ring Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 478df3d..fdee40f 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -561,6 +561,20 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, elem->out_sg[i].iov_len); } +static void virtqueue_detach_element_split(VirtQueue *vq, + const VirtQueueElement *elem, unsigned int len) +{ + vq->inuse--; + virtqueue_unmap_sg(vq, elem, len); +} + +static void virtqueue_detach_element_packed(VirtQueue *vq, + const VirtQueueElement *elem, unsigned int len) +{ + vq->inuse -= elem->count; + virtqueue_unmap_sg(vq, elem, len); +} + /* virtqueue_detach_element: * @vq: The #VirtQueue * @elem: The #VirtQueueElement @@ -573,8 +587,11 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, void virtqueue_detach_element(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { - vq->inuse--; - virtqueue_unmap_sg(vq, elem, len); + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + virtqueue_detach_element_packed(vq, elem, len); + } else { + virtqueue_detach_element_split(vq, elem, len); + } } /* virtqueue_unpop: From patchwork Wed Apr 4 12:54:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894984 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GQyx2mkmz9s0n for ; Wed, 4 Apr 2018 22:59:37 +1000 (AEST) Received: from localhost ([::1]:56284 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3i0l-0003sR-7m for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 08:59:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54263) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hxC-0001GU-El for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hx9-0005eG-1W for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:54 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50834 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hx8-0005dZ-Mr for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:50 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 045DE814DF4C; Wed, 4 Apr 2018 12:55:50 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id CB5F3215CDAF; Wed, 4 Apr 2018 12:55:47 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:54:01 +0800 Message-Id: <1522846444-31725-6-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 04 Apr 2018 12:55:50 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 04 Apr 2018 12:55:50 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 5/8] virtio: notification tweak for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Always enable notify and bypass set notification before supporting driver and device area. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index fdee40f..95a4681 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -425,6 +425,10 @@ void virtio_queue_set_notification(VirtQueue *vq, int enable) { vq->notification = enable; + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + return; + } + if (!vq->vring.desc) { return; } @@ -1801,6 +1805,11 @@ static bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq) { uint16_t old, new; bool v; + + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + return true; + } + /* We need to expose used array entries before checking used event. */ smp_mb(); /* Always notify when queue is empty (when feature acknowledge) */ From patchwork Wed Apr 4 12:54:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894988 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GR6H1LtTz9s0n for ; Wed, 4 Apr 2018 23:05:59 +1000 (AEST) Received: from localhost ([::1]:56621 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3i6u-0000iD-Mi for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 09:05:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54348) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hxG-0001KR-B2 for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:56:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hxC-0005hQ-3c for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:58 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33820 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hxB-0005gD-J0 for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:53 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AD826EB700; Wed, 4 Apr 2018 12:55:52 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8244E215CDAF; Wed, 4 Apr 2018 12:55:50 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:54:02 +0800 Message-Id: <1522846444-31725-7-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 04 Apr 2018 12:55:52 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 04 Apr 2018 12:55:52 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 6/8] virtio: flush/push support for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 104 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 14 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 95a4681..def07c6 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -26,6 +26,7 @@ #define AVAIL_DESC_PACKED(b) ((b) << 7) #define USED_DESC_PACKED(b) ((b) << 15) +#define VIRTQ_F_DESC_USED(w) (AVAIL_DESC_PACKED(w) | USED_DESC_PACKED(w)) /* * The alignment to use between consumer and producer parts of vring. @@ -636,19 +637,11 @@ bool virtqueue_rewind(VirtQueue *vq, unsigned int num) } /* Called within rcu_read_lock(). */ -void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, +static void virtqueue_fill_split(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len, unsigned int idx) { VRingUsedElem uelem; - trace_virtqueue_fill(vq, elem, len, idx); - - virtqueue_unmap_sg(vq, elem, len); - - if (unlikely(vq->vdev->broken)) { - return; - } - if (unlikely(!vq->vring.used)) { return; } @@ -660,16 +653,66 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, vring_used_write(vq, &uelem, idx); } -/* Called within rcu_read_lock(). */ -void virtqueue_flush(VirtQueue *vq, unsigned int count) +static void virtqueue_fill_packed(VirtQueue *vq, const VirtQueueElement *elem) { - uint16_t old, new; + uint16_t i, w, head; + VRingMemoryRegionCaches *caches; + VRingDescPacked desc = { + .addr = 0, + .flags = 0, + }; + + if (unlikely(!vq->packed.desc)) { + return; + } + + w = elem->wrap_counter; + caches = vring_get_region_caches(vq); + for (i = 0; i < elem->count; i++) { + head = (elem->index + i) % vq->packed.num; + /* Don't toggle the first one since it is the originally one */ + if ((i > 0) && (!head)) { + w ^= 1; + } + + desc.id = elem->index; + desc.flags = VIRTQ_F_DESC_USED(w); + desc.len = elem->len[i]; + virtio_tswap16s(vq->vdev, &desc.id); + virtio_tswap32s(vq->vdev, &desc.len); + virtio_tswap16s(vq->vdev, &desc.flags); + address_space_write_cached(&caches->desc, + sizeof(VRingDescPacked) * head, &desc, + sizeof(VRingDescPacked)); + address_space_cache_invalidate(&caches->desc, + sizeof(VRingDescPacked) * head, + sizeof(VRingDescPacked)); + } +} + +void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len, unsigned int idx) +{ + trace_virtqueue_fill(vq, elem, len, idx); + + virtqueue_unmap_sg(vq, elem, len); if (unlikely(vq->vdev->broken)) { - vq->inuse -= count; return; } + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + virtqueue_fill_packed(vq, elem); + } else { + virtqueue_fill_split(vq, elem, len, idx); + } +} + +/* Called within rcu_read_lock(). */ +static void virtqueue_flush_split(VirtQueue *vq, unsigned int count) +{ + uint16_t old, new; + if (unlikely(!vq->vring.used)) { return; } @@ -685,12 +728,45 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count) vq->signalled_used_valid = false; } +static void virtqueue_flush_packed(VirtQueue *vq, unsigned int count) +{ + if (unlikely(!vq->packed.desc)) { + return; + } + + vq->inuse -= count; + + /* FIXME: is this correct? */ + if (vq->inuse) { + return; + } +} + +void virtqueue_flush(VirtQueue *vq, unsigned int count) +{ + if (unlikely(vq->vdev->broken)) { + vq->inuse -= count; + return; + } + + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + virtqueue_flush_packed(vq, count); + } else { + virtqueue_flush_split(vq, count); + } +} + void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { rcu_read_lock(); virtqueue_fill(vq, elem, len, 0); - virtqueue_flush(vq, 1); + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + /* FIXME: How to deal with the length field for chained desc */ + virtqueue_flush(vq, elem->count); + } else { + virtqueue_flush(vq, 1); + } rcu_read_unlock(); } From patchwork Wed Apr 4 12:54:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894982 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GQvr3wX6z9ryG for ; Wed, 4 Apr 2018 22:56:56 +1000 (AEST) Received: from localhost ([::1]:56247 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hyA-0001S5-H7 for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 08:56:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54415) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hxI-0001M2-8i for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:56:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hxE-0005kh-KE for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:56:00 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33828 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hxE-0005jD-27 for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:56 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 645DFEB700; Wed, 4 Apr 2018 12:55:55 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id 37F65215CDAF; Wed, 4 Apr 2018 12:55:52 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:54:03 +0800 Message-Id: <1522846444-31725-8-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 04 Apr 2018 12:55:55 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 04 Apr 2018 12:55:55 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 7/8] virtio: get avail bytes check for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu mostly as same as 1.0, copy it separately for prototype, need a refactoring. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index def07c6..cf726f3 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -836,9 +836,9 @@ static int virtqueue_read_next_desc(VirtIODevice *vdev, VRingDesc *desc, return VIRTQUEUE_READ_DESC_MORE; } -void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, - unsigned int *out_bytes, - unsigned max_in_bytes, unsigned max_out_bytes) +static void virtqueue_get_avail_bytes_split(VirtQueue *vq, + unsigned int *in_bytes, unsigned int *out_bytes, + unsigned max_in_bytes, unsigned max_out_bytes) { VirtIODevice *vdev = vq->vdev; unsigned int max, idx; @@ -961,6 +961,142 @@ err: goto done; } +static void virtqueue_get_avail_bytes_packed(VirtQueue *vq, + unsigned int *in_bytes, unsigned int *out_bytes, + unsigned max_in_bytes, unsigned max_out_bytes) +{ + VirtIODevice *vdev = vq->vdev; + unsigned int max, idx; + unsigned int total_bufs, in_total, out_total; + MemoryRegionCache *desc_cache; + VRingMemoryRegionCaches *caches; + MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID; + int64_t len = 0; + VRingDescPacked desc; + + if (unlikely(!vq->packed.desc)) { + if (in_bytes) { + *in_bytes = 0; + } + if (out_bytes) { + *out_bytes = 0; + } + return; + } + + rcu_read_lock(); + idx = vq->last_avail_idx; + total_bufs = in_total = out_total = 0; + + max = vq->packed.num; + caches = vring_get_region_caches(vq); + if (caches->desc.len < max * sizeof(VRingDescPacked)) { + virtio_error(vdev, "Cannot map descriptor ring"); + goto err; + } + + desc_cache = &caches->desc; + vring_desc_read_packed(vdev, &desc, desc_cache, idx); + while (is_desc_avail(&desc)) { + unsigned int num_bufs; + unsigned int i; + + num_bufs = total_bufs; + + if (desc.flags & VRING_DESC_F_INDIRECT) { + if (desc.len % sizeof(VRingDescPacked)) { + virtio_error(vdev, "Invalid size for indirect buffer table"); + goto err; + } + + /* If we've got too many, that implies a descriptor loop. */ + if (num_bufs >= max) { + virtio_error(vdev, "Looped descriptor"); + goto err; + } + + /* loop over the indirect descriptor table */ + len = address_space_cache_init(&indirect_desc_cache, + vdev->dma_as, + desc.addr, desc.len, false); + desc_cache = &indirect_desc_cache; + if (len < desc.len) { + virtio_error(vdev, "Cannot map indirect buffer"); + goto err; + } + + max = desc.len / sizeof(VRingDescPacked); + num_bufs = i = 0; + vring_desc_read_packed(vdev, &desc, desc_cache, i); + } + + do { + /* If we've got too many, that implies a descriptor loop. */ + if (++num_bufs > max) { + virtio_error(vdev, "Looped descriptor"); + goto err; + } + + if (desc.flags & VRING_DESC_F_WRITE) { + in_total += desc.len; + } else { + out_total += desc.len; + } + if (in_total >= max_in_bytes && out_total >= max_out_bytes) { + goto done; + } + + if (desc_cache == &indirect_desc_cache) { + vring_desc_read_packed(vdev, &desc, desc_cache, + ++i % vq->packed.num); + } else { + vring_desc_read_packed(vdev, &desc, desc_cache, + ++idx % vq->packed.num); + } + } while (desc.flags & VRING_DESC_F_NEXT); + + if (desc_cache == &indirect_desc_cache) { + address_space_cache_destroy(&indirect_desc_cache); + total_bufs++; + /* We missed one step on for indirect desc */ + idx++; + } else { + total_bufs = num_bufs; + } + + desc_cache = &caches->desc; + vring_desc_read_packed(vdev, &desc, desc_cache, idx % vq->packed.num); + } + +done: + address_space_cache_destroy(&indirect_desc_cache); + if (in_bytes) { + *in_bytes = in_total; + } + if (out_bytes) { + *out_bytes = out_total; + } + rcu_read_unlock(); + return; + +err: + in_total = out_total = 0; + goto done; +} + +void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, + unsigned int *out_bytes, + unsigned max_in_bytes, unsigned max_out_bytes) +{ + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + virtqueue_get_avail_bytes_packed(vq, in_bytes, out_bytes, + max_in_bytes, max_out_bytes); + } else { + virtqueue_get_avail_bytes_split(vq, in_bytes, out_bytes, + max_in_bytes, max_out_bytes); + } +} + int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, unsigned int out_bytes) { From patchwork Wed Apr 4 12:54:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 894989 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40GR9V0tM0z9s0n for ; Wed, 4 Apr 2018 23:08:44 +1000 (AEST) Received: from localhost ([::1]:56876 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3i9a-0002t4-99 for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2018 09:08:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54461) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3hxJ-0001NK-Ln for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:56:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3hxH-0005oJ-9R for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:56:01 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:41096 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f3hxG-0005mt-PM for qemu-devel@nongnu.org; Wed, 04 Apr 2018 08:55:59 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1F43E84250; Wed, 4 Apr 2018 12:55:58 +0000 (UTC) Received: from localhost.localdomain (dhcp-14-122.nay.redhat.com [10.66.14.122]) by smtp.corp.redhat.com (Postfix) with ESMTP id E1E15215CDAF; Wed, 4 Apr 2018 12:55:55 +0000 (UTC) From: wexu@redhat.com To: wexu@redhat.com, jasowang@redhat.com, mst@redhat.com, tiwei.bie@intel.com, jfreimann@redhat.com, qemu-devel@nongnu.org Date: Wed, 4 Apr 2018 20:54:04 +0800 Message-Id: <1522846444-31725-9-git-send-email-wexu@redhat.com> In-Reply-To: <1522846444-31725-1-git-send-email-wexu@redhat.com> References: <1522846444-31725-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Wed, 04 Apr 2018 12:55:58 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Wed, 04 Apr 2018 12:55:58 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'wexu@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 8/8] virtio: queue pop support for packed ring X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu cloned from split ring pop, a global static length array and the inside-element length array are introduced to easy prototype, this consumes more memory and it is valuable to move to dynamic allocation as the out/in sg does. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 153 insertions(+), 1 deletion(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index cf726f3..0eafb38 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1221,7 +1221,7 @@ static void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_nu return elem; } -void *virtqueue_pop(VirtQueue *vq, size_t sz) +static void *virtqueue_pop_split(VirtQueue *vq, size_t sz) { unsigned int i, head, max; VRingMemoryRegionCaches *caches; @@ -1356,6 +1356,158 @@ err_undo_map: goto done; } +static uint16_t dma_len[VIRTQUEUE_MAX_SIZE]; +static void *virtqueue_pop_packed(VirtQueue *vq, size_t sz) +{ + unsigned int i, head, max; + VRingMemoryRegionCaches *caches; + MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID; + MemoryRegionCache *cache; + int64_t len; + VirtIODevice *vdev = vq->vdev; + VirtQueueElement *elem = NULL; + unsigned out_num, in_num, elem_entries; + hwaddr addr[VIRTQUEUE_MAX_SIZE]; + struct iovec iov[VIRTQUEUE_MAX_SIZE]; + VRingDescPacked desc; + uint8_t wrap_counter; + + if (unlikely(vdev->broken)) { + return NULL; + } + + vq->last_avail_idx %= vq->packed.num; + + rcu_read_lock(); + if (virtio_queue_empty_packed_rcu(vq)) { + goto done; + } + + /* When we start there are none of either input nor output. */ + out_num = in_num = elem_entries = 0; + + max = vq->vring.num; + + if (vq->inuse >= vq->vring.num) { + virtio_error(vdev, "Virtqueue size exceeded"); + goto done; + } + + if (virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) { + /* FIXME: TBD */ + } + + head = vq->last_avail_idx; + i = head; + + caches = vring_get_region_caches(vq); + cache = &caches->desc_packed; + vring_desc_read_packed(vdev, &desc, cache, i); + if (desc.flags & VRING_DESC_F_INDIRECT) { + if (desc.len % sizeof(VRingDescPacked)) { + virtio_error(vdev, "Invalid size for indirect buffer table"); + goto done; + } + + /* loop over the indirect descriptor table */ + len = address_space_cache_init(&indirect_desc_cache, vdev->dma_as, + desc.addr, desc.len, false); + cache = &indirect_desc_cache; + if (len < desc.len) { + virtio_error(vdev, "Cannot map indirect buffer"); + goto done; + } + + max = desc.len / sizeof(VRingDescPacked); + i = 0; + vring_desc_read_packed(vdev, &desc, cache, i); + } + + wrap_counter = vq->wrap_counter; + /* Collect all the descriptors */ + while (1) { + bool map_ok; + + if (desc.flags & VRING_DESC_F_WRITE) { + map_ok = virtqueue_map_desc(vdev, &in_num, addr + out_num, + iov + out_num, + VIRTQUEUE_MAX_SIZE - out_num, true, + desc.addr, desc.len); + } else { + if (in_num) { + virtio_error(vdev, "Incorrect order for descriptors"); + goto err_undo_map; + } + map_ok = virtqueue_map_desc(vdev, &out_num, addr, iov, + VIRTQUEUE_MAX_SIZE, false, + desc.addr, desc.len); + } + if (!map_ok) { + goto err_undo_map; + } + + /* If we've got too many, that implies a descriptor loop. */ + if (++elem_entries > max) { + virtio_error(vdev, "Looped descriptor"); + goto err_undo_map; + } + + dma_len[i++] = desc.len; + /* Toggle wrap_counter for non indirect desc */ + if ((i == vq->packed.num) && (cache != &indirect_desc_cache)) { + vq->wrap_counter ^= 1; + } + + if (desc.flags & VRING_DESC_F_NEXT) { + vring_desc_read_packed(vq->vdev, &desc, cache, i % vq->packed.num); + } else { + break; + } + } + + /* Now copy what we have collected and mapped */ + elem = virtqueue_alloc_element(sz, out_num, in_num); + elem->index = head; + elem->wrap_counter = wrap_counter; + elem->count = (cache == &indirect_desc_cache) ? 1 : out_num + in_num; + for (i = 0; i < out_num; i++) { + /* DMA Done by marking the length as 0 */ + elem->len[i] = 0; + elem->out_addr[i] = addr[i]; + elem->out_sg[i] = iov[i]; + } + for (i = 0; i < in_num; i++) { + elem->len[out_num + i] = dma_len[head + out_num + i]; + elem->in_addr[i] = addr[out_num + i]; + elem->in_sg[i] = iov[out_num + i]; + } + + vq->last_avail_idx += elem->count; + vq->last_avail_idx %= vq->packed.num; + vq->inuse += elem->count; + + trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num); +done: + address_space_cache_destroy(&indirect_desc_cache); + rcu_read_unlock(); + + return elem; + +err_undo_map: + virtqueue_undo_map_desc(out_num, in_num, iov); + g_free(elem); + goto done; +} + +void *virtqueue_pop(VirtQueue *vq, size_t sz) +{ + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + return virtqueue_pop_packed(vq, sz); + } else { + return virtqueue_pop_split(vq, sz); + } +} + /* virtqueue_drop_all: * @vq: The #VirtQueue * Drops all queued buffers and indicates them to the guest