From patchwork Thu Oct 11 14:08:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982504 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCbP5sH1z9s4s for ; Fri, 12 Oct 2018 01:12:33 +1100 (AEDT) Received: from localhost ([::1]:34696 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbhX-0006t0-B6 for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:12:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39178) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeB-0004gU-UG for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeA-0005kV-Va for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46260) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeA-0005k4-MY for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:02 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 13B7E308338F; Thu, 11 Oct 2018 14:09:02 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 280005D6A9; Thu, 11 Oct 2018 14:08:59 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:24 -0400 Message-Id: <1539266915-15216-2-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 11 Oct 2018 14:09:02 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 01/12] virtio: introduce packed ring definitions 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu sync from 1.1 spec Signed-off-by: Wei Xu --- include/standard-headers/linux/virtio_config.h | 15 +++++++++ include/standard-headers/linux/virtio_ring.h | 43 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h index 0b19436..9f450fd 100644 --- a/include/standard-headers/linux/virtio_config.h +++ b/include/standard-headers/linux/virtio_config.h @@ -75,6 +75,21 @@ */ #define VIRTIO_F_IOMMU_PLATFORM 33 +/* This feature indicates support for the packed virtqueue layout. */ +#define VIRTIO_F_RING_PACKED 34 + +/* Enable events */ +#define RING_EVENT_FLAGS_ENABLE 0x0 +/* Disable events */ +#define RING_EVENT_FLAGS_DISABLE 0x1 +/* + * * Enable events for a specific descriptor + * * (as specified by Descriptor Ring Change Event Offset/Wrap Counter). + * * Only valid if VIRTIO_F_RING_EVENT_IDX has been negotiated. + * */ +#define RING_EVENT_FLAGS_DESC 0x2 +/* The value 0x3 is reserved */ + /* * Does the device support Single Root I/O Virtualization? */ diff --git a/include/standard-headers/linux/virtio_ring.h b/include/standard-headers/linux/virtio_ring.h index d26e72b..1719c6f 100644 --- a/include/standard-headers/linux/virtio_ring.h +++ b/include/standard-headers/linux/virtio_ring.h @@ -42,6 +42,10 @@ /* This means the buffer contains a list of buffer descriptors. */ #define VRING_DESC_F_INDIRECT 4 +/* Mark a descriptor as available or used. */ +#define VRING_DESC_F_AVAIL (1ul << 7) +#define VRING_DESC_F_USED (1ul << 15) + /* The Host uses this in used->flags to advise the Guest: don't kick me when * you add a buffer. It's unreliable, so it's simply an optimization. Guest * will still kick if it's out of buffers. */ @@ -51,6 +55,17 @@ * optimization. */ #define VRING_AVAIL_F_NO_INTERRUPT 1 +/* Enable events. */ +#define VRING_EVENT_F_ENABLE 0x0 +/* Disable events. */ +#define VRING_EVENT_F_DISABLE 0x1 +/* + * Enable events for a specific descriptor + * (as specified by Descriptor Ring Change Event Offset/Wrap Counter). + * Only valid if VIRTIO_RING_F_EVENT_IDX has been negotiated. + */ +#define VRING_EVENT_F_DESC 0x2 + /* We support indirect buffer descriptors */ #define VIRTIO_RING_F_INDIRECT_DESC 28 @@ -169,4 +184,32 @@ static inline int vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_ return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old); } +struct vring_packed_desc_event { + /* Descriptor Ring Change Event Offset/Wrap Counter. */ + __virtio16 off_wrap; + /* Descriptor Ring Change Event Flags. */ + __virtio16 flags; +}; + +struct vring_packed_desc { + /* Buffer Address. */ + __virtio64 addr; + /* Buffer Length. */ + __virtio32 len; + /* Buffer ID. */ + __virtio16 id; + /* The flags depending on descriptor type. */ + __virtio16 flags; +}; + +struct vring_packed { + unsigned int num; + + struct vring_packed_desc *desc; + + struct vring_packed_desc_event *driver; + + struct vring_packed_desc_event *device; +}; + #endif /* _LINUX_VIRTIO_RING_H */ From patchwork Thu Oct 11 14:08:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982507 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCcd04Wxz9s4s for ; Fri, 12 Oct 2018 01:13:37 +1100 (AEDT) Received: from localhost ([::1]:34703 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbiY-0007t6-57 for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:13:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39261) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeJ-0004mI-D0 for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeD-0005nF-Ki for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46284) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeD-0005mE-El for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:05 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B9FCB3083395; Thu, 11 Oct 2018 14:09:04 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8BD115D6A9; Thu, 11 Oct 2018 14:09:02 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:25 -0400 Message-Id: <1539266915-15216-3-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 11 Oct 2018 14:09:04 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 02/12] virtio: redefine structure & 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Redefine packed ring structure according to qemu nomenclature, also supported data(event index, wrap counter, etc) are introduced. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 94f5c8e..500eecf 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -39,6 +39,13 @@ typedef struct VRingDesc uint16_t next; } VRingDesc; +typedef struct VRingPackedDesc { + uint64_t addr; + uint32_t len; + uint16_t id; + uint16_t flags; +} VRingPackedDesc; + typedef struct VRingAvail { uint16_t flags; @@ -62,8 +69,14 @@ typedef struct VRingUsed typedef struct VRingMemoryRegionCaches { struct rcu_head rcu; MemoryRegionCache desc; - MemoryRegionCache avail; - MemoryRegionCache used; + union { + MemoryRegionCache avail; + MemoryRegionCache driver; + }; + union { + MemoryRegionCache used; + MemoryRegionCache device; + }; } VRingMemoryRegionCaches; typedef struct VRing @@ -77,6 +90,11 @@ typedef struct VRing VRingMemoryRegionCaches *caches; } VRing; +typedef struct VRingPackedDescEvent { + uint16_t off_wrap; + uint16_t flags; +} VRingPackedDescEvent ; + struct VirtQueue { VRing vring; @@ -87,6 +105,10 @@ struct VirtQueue /* Last avail_idx read from VQ. */ uint16_t shadow_avail_idx; + uint16_t event_idx; + bool event_wrap_counter; + bool avail_wrap_counter; + uint16_t used_idx; /* Last used index value we have signalled on */ From patchwork Thu Oct 11 14:08:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982503 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCXr2w23z9s3l for ; Fri, 12 Oct 2018 01:10:20 +1100 (AEDT) Received: from localhost ([::1]:34684 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbfN-00053D-VW for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:10:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39277) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeL-0004no-FR for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeG-0005uc-60 for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45718) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeF-0005u3-TA for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:08 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3DB3290C7A; Thu, 11 Oct 2018 14:09:07 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3BDDA62A3E; Thu, 11 Oct 2018 14:09:04 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:26 -0400 Message-Id: <1539266915-15216-4-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 11 Oct 2018 14:09:07 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 03/12] virtio: init 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Expand 1.0 by adding offset calculation accordingly. Signed-off-by: Wei Xu --- hw/virtio/vhost.c | 16 ++++++++-------- hw/virtio/virtio.c | 35 +++++++++++++++++++++++------------ include/hw/virtio/virtio.h | 4 ++-- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 569c405..9df2da3 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -996,14 +996,14 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, r = -ENOMEM; goto fail_alloc_desc; } - vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx); + vq->avail_size = s = l = virtio_queue_get_driver_size(vdev, idx); vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx); vq->avail = vhost_memory_map(dev, a, &l, 0); if (!vq->avail || l != s) { r = -ENOMEM; goto fail_alloc_avail; } - vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx); + vq->used_size = s = l = virtio_queue_get_device_size(vdev, idx); vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx); vq->used = vhost_memory_map(dev, a, &l, 1); if (!vq->used || l != s) { @@ -1051,10 +1051,10 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, fail_vector: fail_kick: fail_alloc: - vhost_memory_unmap(dev, vq->used, virtio_queue_get_used_size(vdev, idx), + vhost_memory_unmap(dev, vq->used, virtio_queue_get_device_size(vdev, idx), 0, 0); fail_alloc_used: - vhost_memory_unmap(dev, vq->avail, virtio_queue_get_avail_size(vdev, idx), + vhost_memory_unmap(dev, vq->avail, virtio_queue_get_driver_size(vdev, idx), 0, 0); fail_alloc_avail: vhost_memory_unmap(dev, vq->desc, virtio_queue_get_desc_size(vdev, idx), @@ -1101,10 +1101,10 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, vhost_vq_index); } - vhost_memory_unmap(dev, vq->used, virtio_queue_get_used_size(vdev, idx), - 1, virtio_queue_get_used_size(vdev, idx)); - vhost_memory_unmap(dev, vq->avail, virtio_queue_get_avail_size(vdev, idx), - 0, virtio_queue_get_avail_size(vdev, idx)); + vhost_memory_unmap(dev, vq->used, virtio_queue_get_device_size(vdev, idx), + 1, virtio_queue_get_device_size(vdev, idx)); + vhost_memory_unmap(dev, vq->avail, virtio_queue_get_driver_size(vdev, idx), + 0, virtio_queue_get_driver_size(vdev, idx)); vhost_memory_unmap(dev, vq->desc, virtio_queue_get_desc_size(vdev, idx), 0, virtio_queue_get_desc_size(vdev, idx)); } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 500eecf..bfb3364 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -162,11 +162,8 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n) VRingMemoryRegionCaches *old = vq->vring.caches; VRingMemoryRegionCaches *new = NULL; hwaddr addr, size; - int event_size; int64_t len; - event_size = virtio_vdev_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; - addr = vq->vring.desc; if (!addr) { goto out_no_cache; @@ -174,13 +171,13 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n) new = g_new0(VRingMemoryRegionCaches, 1); size = virtio_queue_get_desc_size(vdev, n); len = address_space_cache_init(&new->desc, vdev->dma_as, - addr, size, false); + addr, size, true); if (len < size) { virtio_error(vdev, "Cannot map desc"); goto err_desc; } - size = virtio_queue_get_used_size(vdev, n) + event_size; + size = virtio_queue_get_device_size(vdev, n); len = address_space_cache_init(&new->used, vdev->dma_as, vq->vring.used, size, true); if (len < size) { @@ -188,7 +185,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n) goto err_used; } - size = virtio_queue_get_avail_size(vdev, n) + event_size; + size = virtio_queue_get_driver_size(vdev, n); len = address_space_cache_init(&new->avail, vdev->dma_as, vq->vring.avail, size, false); if (len < size) { @@ -2339,16 +2336,30 @@ hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n) return sizeof(VRingDesc) * vdev->vq[n].vring.num; } -hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n) +hwaddr virtio_queue_get_driver_size(VirtIODevice *vdev, int n) { - return offsetof(VRingAvail, ring) + - sizeof(uint16_t) * vdev->vq[n].vring.num; + int s; + + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + return sizeof(struct VRingPackedDescEvent); + } else { + s = virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; + return offsetof(VRingAvail, ring) + + sizeof(uint16_t) * vdev->vq[n].vring.num + s; + } } -hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n) +hwaddr virtio_queue_get_device_size(VirtIODevice *vdev, int n) { - return offsetof(VRingUsed, ring) + - sizeof(VRingUsedElem) * vdev->vq[n].vring.num; + int s; + + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + return sizeof(struct VRingPackedDescEvent); + } else { + s = virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; + return offsetof(VRingUsed, ring) + + sizeof(VRingUsedElem) * vdev->vq[n].vring.num + s; + } } uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 9c1fa07..e323e76 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -270,8 +270,8 @@ hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n); -hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n); -hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n); +hwaddr virtio_queue_get_driver_size(VirtIODevice *vdev, int n); +hwaddr virtio_queue_get_device_size(VirtIODevice *vdev, int n); uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n); void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx); void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n); From patchwork Thu Oct 11 14:08:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982508 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCfp2H4lz9s4s for ; Fri, 12 Oct 2018 01:15:30 +1100 (AEDT) Received: from localhost ([::1]:34711 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbkN-0000vE-OC for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:15:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39290) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeP-0004p5-IW for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeJ-0005wi-2O for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38210) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeI-0005vX-KC for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:10 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D5BB93084027; Thu, 11 Oct 2018 14:09:09 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id AA1605D6A9; Thu, 11 Oct 2018 14:09:07 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:27 -0400 Message-Id: <1539266915-15216-5-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Thu, 11 Oct 2018 14:09:09 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 04/12] virtio: init wrap counter 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com 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 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index bfb3364..9185efb 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1243,6 +1243,9 @@ void virtio_reset(void *opaque) vdev->vq[i].last_avail_idx = 0; vdev->vq[i].shadow_avail_idx = 0; vdev->vq[i].used_idx = 0; + vdev->vq[i].avail_wrap_counter = true; + vdev->vq[i].event_idx = 0; + vdev->vq[i].event_wrap_counter = true; virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR); vdev->vq[i].signalled_used = 0; vdev->vq[i].signalled_used_valid = false; From patchwork Thu Oct 11 14:08:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982502 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCXZ0ZNDz9s3l for ; Fri, 12 Oct 2018 01:10:06 +1100 (AEDT) Received: from localhost ([::1]:34683 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbf9-0004r8-Jg for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:10:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeP-0004p6-IX for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeL-0005zI-PH for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:65252) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeL-0005xl-Ep for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:13 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8C78D308A953; Thu, 11 Oct 2018 14:09:12 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 59D3E5D6A9; Thu, 11 Oct 2018 14:09:10 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:28 -0400 Message-Id: <1539266915-15216-6-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Thu, 11 Oct 2018 14:09:12 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 05/12] virtio: init and desc 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Basic initialization and helpers for packed ring. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 9185efb..86f88da 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 @@ -372,6 +375,23 @@ int virtio_queue_ready(VirtQueue *vq) return vq->vring.avail != 0; } +static void vring_packed_desc_read_flags(VirtIODevice *vdev, + VRingPackedDesc *desc, MemoryRegionCache *cache, int i) +{ + address_space_read_cached(cache, + i * sizeof(VRingPackedDesc) + offsetof(VRingPackedDesc, flags), + &desc->flags, sizeof(desc->flags)); +} + +static inline bool is_desc_avail(struct VRingPackedDesc *desc, bool wc) +{ + bool avail, used; + + avail = !!(desc->flags & AVAIL_DESC_PACKED(1)); + used = !!(desc->flags & USED_DESC_PACKED(1)); + return (avail != used) && (avail == wc); +} + /* Fetch avail_idx from VQ memory only when we really need to know if * guest has added some buffers. * Called within rcu_read_lock(). */ @@ -392,7 +412,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_split_empty(VirtQueue *vq) { bool empty; @@ -414,6 +434,41 @@ int virtio_queue_empty(VirtQueue *vq) return empty; } +static int virtio_queue_packed_empty_rcu(VirtQueue *vq) +{ + struct VRingPackedDesc desc; + VRingMemoryRegionCaches *cache; + + if (unlikely(!vq->vring.desc)) { + return 1; + } + + cache = vring_get_region_caches(vq); + vring_packed_desc_read_flags(vq->vdev, &desc, &cache->desc, + vq->last_avail_idx); + + return !is_desc_avail(&desc, vq->avail_wrap_counter); +} + +static int virtio_queue_packed_empty(VirtQueue *vq) +{ + bool empty; + + rcu_read_lock(); + empty = virtio_queue_packed_empty_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_packed_empty(vq); + } else { + return virtio_queue_split_empty(vq); + } +} + static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { From patchwork Thu Oct 11 14:08:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982512 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCh66XP2z9s4s for ; Fri, 12 Oct 2018 01:16:38 +1100 (AEDT) Received: from localhost ([::1]:34723 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAblU-0001oX-A5 for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:16:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39310) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeT-0004sx-ID for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeP-000620-WE for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35882) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeP-00060H-G4 for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:17 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3AC8E80467; Thu, 11 Oct 2018 14:09:15 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D5C55D6A9; Thu, 11 Oct 2018 14:09:12 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:29 -0400 Message-Id: <1539266915-15216-7-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 11 Oct 2018 14:09:15 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 06/12] 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Same thought as 1.0 except a bit confused when trying to reuse 'shadow_avail_idx', so the interrelated new event_idx and the wrap counter for notifications has been introduced in previous patch. Signed-off-by: Wei Xu --- hw/virtio/virtio.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 86f88da..13c6c98 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -375,6 +375,17 @@ int virtio_queue_ready(VirtQueue *vq) return vq->vring.avail != 0; } +static void vring_packed_desc_read(VirtIODevice *vdev, VRingPackedDesc *desc, + MemoryRegionCache *cache, int i) +{ + address_space_read_cached(cache, i * sizeof(VRingPackedDesc), + desc, sizeof(VRingPackedDesc)); + virtio_tswap16s(vdev, &desc->flags); + virtio_tswap64s(vdev, &desc->addr); + virtio_tswap32s(vdev, &desc->len); + virtio_tswap16s(vdev, &desc->id); +} + static void vring_packed_desc_read_flags(VirtIODevice *vdev, VRingPackedDesc *desc, MemoryRegionCache *cache, int i) { @@ -672,9 +683,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_split_get_avail_bytes(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; @@ -797,6 +808,165 @@ err: goto done; } +static void virtqueue_packed_get_avail_bytes(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; + VRingPackedDesc desc; + bool wrap_counter; + + if (unlikely(!vq->vring.desc)) { + if (in_bytes) { + *in_bytes = 0; + } + if (out_bytes) { + *out_bytes = 0; + } + return; + } + + rcu_read_lock(); + idx = vq->last_avail_idx; + wrap_counter = vq->avail_wrap_counter; + total_bufs = in_total = out_total = 0; + + max = vq->vring.num; + caches = vring_get_region_caches(vq); + if (caches->desc.len < max * sizeof(VRingPackedDesc)) { + virtio_error(vdev, "Cannot map descriptor ring"); + goto err; + } + + desc_cache = &caches->desc; + vring_packed_desc_read(vdev, &desc, desc_cache, idx); + /* Make sure we see all the fields*/ + smp_rmb(); + while (is_desc_avail(&desc, wrap_counter)) { + unsigned int num_bufs; + unsigned int i = 0; + + num_bufs = total_bufs; + + if (desc.flags & VRING_DESC_F_INDIRECT) { + if (desc.len % sizeof(VRingPackedDesc)) { + 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(VRingPackedDesc); + num_bufs = i = 0; + vring_packed_desc_read(vdev, &desc, desc_cache, i); + /* Make sure we see all the fields*/ + smp_rmb(); + } + + 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) { + if (++i > vq->vring.num) { + virtio_error(vdev, "Looped descriptor"); + goto err; + } + vring_packed_desc_read(vdev, &desc, desc_cache, i); + } else { + if (++idx >= vq->vring.num) { + idx -= vq->vring.num; + wrap_counter = !wrap_counter; + } + vring_packed_desc_read(vdev, &desc, desc_cache, idx); + } + /* Make sure we see the flags */ + smp_rmb(); + } 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++; + if (++idx >= vq->vring.num) { + idx -= vq->vring.num; + wrap_counter = !wrap_counter; + } + } else { + total_bufs = num_bufs; + } + + desc_cache = &caches->desc; + vring_packed_desc_read(vdev, &desc, desc_cache, idx); + /* Make sure we see all the fields */ + smp_rmb(); + } + + /* Set up index and wrap counter for an interrupt when no enough desc */ + vq->event_idx = idx; + vq->event_wrap_counter = wrap_counter; +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_packed_get_avail_bytes(vq, in_bytes, out_bytes, + max_in_bytes, max_out_bytes); + } else { + virtqueue_split_get_avail_bytes(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 Thu Oct 11 14:08:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982505 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCbz2C6jz9s4s for ; Fri, 12 Oct 2018 01:13:03 +1100 (AEDT) Received: from localhost ([::1]:34700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbi0-0007I3-OG for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:13:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39334) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeZ-0004wX-Am for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeV-00064i-Be for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47181) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeS-00061o-0l for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:21 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A376880471; Thu, 11 Oct 2018 14:09:17 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id B37185D6A9; Thu, 11 Oct 2018 14:09:15 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:30 -0400 Message-Id: <1539266915-15216-8-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 11 Oct 2018 14:09:17 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 07/12] virtio: fill/flush/pop 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com 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 | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 244 insertions(+), 14 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 13c6c98..d12a7e3 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -386,6 +386,21 @@ static void vring_packed_desc_read(VirtIODevice *vdev, VRingPackedDesc *desc, virtio_tswap16s(vdev, &desc->id); } +static void vring_packed_desc_write(VirtIODevice *vdev, VRingPackedDesc *desc, + MemoryRegionCache *cache, int i) +{ + virtio_tswap64s(vdev, &desc->addr); + virtio_tswap32s(vdev, &desc->len); + virtio_tswap16s(vdev, &desc->id); + virtio_tswap16s(vdev, &desc->flags); + address_space_write_cached(cache, + sizeof(VRingPackedDesc) * i, desc, + sizeof(VRingPackedDesc)); + address_space_cache_invalidate(cache, + sizeof(VRingPackedDesc) * i, + sizeof(VRingPackedDesc)); +} + static void vring_packed_desc_read_flags(VirtIODevice *vdev, VRingPackedDesc *desc, MemoryRegionCache *cache, int i) { @@ -559,19 +574,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_split_fill(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; } @@ -583,16 +590,64 @@ 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_packed_fill(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len, unsigned int idx) { - uint16_t old, new; + uint16_t w, head; + VRingMemoryRegionCaches *caches; + VRingPackedDesc desc = { + .addr = 0, + .flags = 0, + }; + + if (unlikely(!vq->vring.desc)) { + return; + } + + caches = vring_get_region_caches(vq); + head = vq->used_idx + idx; + head = head >= vq->vring.num ? (head - vq->vring.num) : head; + vring_packed_desc_read(vq->vdev, &desc, &caches->desc, head); + + w = (desc.flags & AVAIL_DESC_PACKED(1)) >> 7; + desc.flags &= ~(AVAIL_DESC_PACKED(1) | USED_DESC_PACKED(1)); + desc.flags |= AVAIL_DESC_PACKED(w) | USED_DESC_PACKED(w); + if (!(desc.flags & VRING_DESC_F_INDIRECT)) { + if (!(desc.flags & VRING_DESC_F_WRITE)) { + desc.len = 0; + } else { + desc.len = len; + } + } + vring_packed_desc_write(vq->vdev, &desc, &caches->desc, head); + + /* Make sure flags has been updated */ + smp_mb(); +} + +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_packed_fill(vq, elem, len, idx); + } else { + virtqueue_split_fill(vq, elem, len, idx); + } +} + +/* Called within rcu_read_lock(). */ +static void virtqueue_split_flush(VirtQueue *vq, unsigned int count) +{ + uint16_t old, new; + if (unlikely(!vq->vring.used)) { return; } @@ -608,6 +663,33 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count) vq->signalled_used_valid = false; } +static void virtqueue_packed_flush(VirtQueue *vq, unsigned int count) +{ + if (unlikely(!vq->vring.desc)) { + return; + } + + vq->inuse -= count; + vq->used_idx += count; + if (vq->used_idx >= vq->vring.num) { + vq->used_idx -= vq->vring.num; + } +} + +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_packed_flush(vq, count); + } else { + virtqueue_split_flush(vq, count); + } +} + void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { @@ -1091,7 +1173,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_split_pop(VirtQueue *vq, size_t sz) { unsigned int i, head, max; VRingMemoryRegionCaches *caches; @@ -1226,6 +1308,154 @@ err_undo_map: goto done; } +static void *virtqueue_packed_pop(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]; + VRingPackedDesc desc; + + if (unlikely(vdev->broken)) { + return NULL; + } + + rcu_read_lock(); + if (virtio_queue_packed_empty_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; + } + + head = vq->last_avail_idx; + i = head; + + caches = vring_get_region_caches(vq); + cache = &caches->desc; + vring_packed_desc_read(vdev, &desc, cache, i); + /* Make sure we see all the fields*/ + smp_rmb(); + if (desc.flags & VRING_DESC_F_INDIRECT) { + if (desc.len % sizeof(VRingPackedDesc)) { + 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(VRingPackedDesc); + i = 0; + vring_packed_desc_read(vdev, &desc, cache, i); + /* Make sure we see all the fields*/ + smp_rmb(); + } + + /* 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; + } + + if (++i >= vq->vring.num) { + i -= vq->vring.num; + } + + if (desc.flags & VRING_DESC_F_NEXT) { + vring_packed_desc_read(vq->vdev, &desc, cache, i); + /* Make sure we see all the fields*/ + smp_rmb(); + } else { + break; + } + } + + /* Now copy what we have collected and mapped */ + elem = virtqueue_alloc_element(sz, out_num, in_num); + for (i = 0; i < out_num; i++) { + elem->out_addr[i] = addr[i]; + elem->out_sg[i] = iov[i]; + } + for (i = 0; i < in_num; i++) { + elem->in_addr[i] = addr[head + out_num + i]; + elem->in_sg[i] = iov[out_num + i]; + } + + vq->last_avail_idx += (cache == &indirect_desc_cache) ? + 1 : out_num + in_num; + if (vq->last_avail_idx >= vq->vring.num) { + vq->last_avail_idx -= vq->vring.num; + vq->avail_wrap_counter = !vq->avail_wrap_counter; + } + vq->inuse++; + + vq->event_idx = vq->last_avail_idx; + vq->event_wrap_counter = vq->avail_wrap_counter; + + 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_packed_pop(vq, sz); + } else { + return virtqueue_split_pop(vq, sz); + } +} + /* virtqueue_drop_all: * @vq: The #VirtQueue * Drops all queued buffers and indicates them to the guest From patchwork Thu Oct 11 14:08:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982509 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCgR3DZFz9s4s for ; Fri, 12 Oct 2018 01:16:03 +1100 (AEDT) Received: from localhost ([::1]:34716 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbku-0001Nv-Vv for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:16:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39347) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbeb-0004wz-9P for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeZ-00066b-9R for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42122) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeV-00062t-Bb for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:25 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 136633002881; Thu, 11 Oct 2018 14:09:20 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 26B7E5D6A9; Thu, 11 Oct 2018 14:09:17 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:31 -0400 Message-Id: <1539266915-15216-9-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Thu, 11 Oct 2018 14:09:20 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 08/12] virtio: event suppression 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com 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 | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index d12a7e3..1d25776 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -241,6 +241,30 @@ static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc, virtio_tswap16s(vdev, &desc->next); } +static void vring_packed_event_read(VirtIODevice *vdev, + MemoryRegionCache *cache, VRingPackedDescEvent *e) +{ + address_space_read_cached(cache, 0, e, sizeof(*e)); + virtio_tswap16s(vdev, &e->off_wrap); + virtio_tswap16s(vdev, &e->flags); +} + +static void vring_packed_off_wrap_write(VirtIODevice *vdev, + MemoryRegionCache *cache, uint16_t off_wrap) +{ + virtio_tswap16s(vdev, &off_wrap); + address_space_write_cached(cache, 0, &off_wrap, sizeof(off_wrap)); + address_space_cache_invalidate(cache, 0, sizeof(off_wrap)); +} + +static void vring_packed_flags_write(VirtIODevice *vdev, + MemoryRegionCache *cache, uint16_t flags) +{ + virtio_tswap16s(vdev, &flags); + address_space_write_cached(cache, sizeof(uint16_t), &flags, sizeof(flags)); + address_space_cache_invalidate(cache, sizeof(uint16_t), sizeof(flags)); +} + static VRingMemoryRegionCaches *vring_get_region_caches(struct VirtQueue *vq) { VRingMemoryRegionCaches *caches = atomic_rcu_read(&vq->vring.caches); @@ -347,7 +371,7 @@ static inline void vring_set_avail_event(VirtQueue *vq, uint16_t val) address_space_cache_invalidate(&caches->used, pa, sizeof(val)); } -void virtio_queue_set_notification(VirtQueue *vq, int enable) +static void virtio_queue_set_notification_split(VirtQueue *vq, int enable) { vq->notification = enable; @@ -370,6 +394,51 @@ void virtio_queue_set_notification(VirtQueue *vq, int enable) rcu_read_unlock(); } +static void virtio_queue_set_notification_packed(VirtQueue *vq, int enable) +{ + VRingPackedDescEvent e; + VRingMemoryRegionCaches *caches; + + rcu_read_lock(); + caches = vring_get_region_caches(vq); + vring_packed_event_read(vq->vdev, &caches->device, &e); + + if (!enable) { + e.flags = RING_EVENT_FLAGS_DISABLE; + goto out; + } + + e.flags = RING_EVENT_FLAGS_ENABLE; + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + uint16_t off_wrap = vq->event_idx | vq->event_wrap_counter << 15; + + vring_packed_off_wrap_write(vq->vdev, &caches->device, off_wrap); + /* Make sure off_wrap is wrote before flags */ + smp_wmb(); + + e.flags = RING_EVENT_FLAGS_DESC; + } + +out: + vring_packed_flags_write(vq->vdev, &caches->device, e.flags); + rcu_read_unlock(); +} + +void virtio_queue_set_notification(VirtQueue *vq, int enable) +{ + vq->notification = enable; + + if (!vq->vring.desc) { + return; + } + + if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { + virtio_queue_set_notification_packed(vq, enable); + } else { + virtio_queue_set_notification_split(vq, enable); + } +} + int virtio_queue_ready(VirtQueue *vq) { return vq->vring.avail != 0; @@ -2103,8 +2172,7 @@ static void virtio_set_isr(VirtIODevice *vdev, int value) } } -/* Called within rcu_read_lock(). */ -static bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq) +static bool virtio_split_should_notify(VirtIODevice *vdev, VirtQueue *vq) { uint16_t old, new; bool v; @@ -2127,6 +2195,58 @@ static bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq) return !v || vring_need_event(vring_get_used_event(vq), new, old); } +static bool vring_packed_need_event(VirtQueue *vq, uint16_t off_wrap, + uint16_t new, uint16_t old) +{ + bool wrap = vq->event_wrap_counter; + int off = off_wrap & ~(1 << 15); + + if (new < old) { + new += vq->vring.num; + wrap ^= 1; + } + + if (wrap != off_wrap >> 15) { + off += vq->vring.num; + } + + return vring_need_event(off, new, old); +} + +static bool virtio_packed_should_notify(VirtIODevice *vdev, VirtQueue *vq) +{ + VRingPackedDescEvent e; + uint16_t old, new; + bool v; + VRingMemoryRegionCaches *caches; + + caches = vring_get_region_caches(vq); + vring_packed_event_read(vdev, &caches->driver, &e); + + old = vq->signalled_used; + new = vq->signalled_used = vq->used_idx; + v = vq->signalled_used_valid; + vq->signalled_used_valid = true; + + if (e.flags == RING_EVENT_FLAGS_DISABLE) { + return false; + } else if (e.flags == RING_EVENT_FLAGS_ENABLE) { + return true; + } + + return !v || vring_packed_need_event(vq, e.off_wrap, new, old); +} + +/* Called within rcu_read_lock(). */ +static bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq) +{ + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + return virtio_packed_should_notify(vdev, vq); + } else { + return virtio_split_should_notify(vdev, vq); + } +} + void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq) { bool should_notify; From patchwork Thu Oct 11 14:08:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982514 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCnQ1XKvz9s5b for ; Fri, 12 Oct 2018 01:21:14 +1100 (AEDT) Received: from localhost ([::1]:34757 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbpv-0005Cv-NV for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:21:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39380) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbef-00050k-6D for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbed-00068m-88 for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:3519) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeb-00064X-5o for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:29 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B8A485F724; Thu, 11 Oct 2018 14:09:22 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8B21D5D6A9; Thu, 11 Oct 2018 14:09:20 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:32 -0400 Message-Id: <1539266915-15216-10-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 11 Oct 2018 14:09:22 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 09/12] virtio-net: fill head desc after done all in a chain 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu With the support of marking a descriptor used/unused in 'flags' field for 1.1, the current way of filling a chained descriptors does not work since driver side may get the wrong 'num_buffer' information in case of the head descriptor has been filled in while the subsequent ones are still in processing in device side. This patch fills the head one after done all the others one. Signed-off-by: Wei Xu --- hw/net/virtio-net.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 4bdd5b8..186c86cd2 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1198,6 +1198,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, struct virtio_net_hdr_mrg_rxbuf mhdr; unsigned mhdr_cnt = 0; size_t offset, i, guest_offset; + VirtQueueElement head; + int head_len = 0; if (!virtio_net_can_receive(nc)) { return -1; @@ -1275,7 +1277,13 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, } /* signal other side */ - virtqueue_fill(q->rx_vq, elem, total, i++); + if (i == 0) { + head_len = total; + head = *elem; + } else { + virtqueue_fill(q->rx_vq, elem, len, i); + } + i++; g_free(elem); } @@ -1286,6 +1294,7 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, &mhdr.num_buffers, sizeof mhdr.num_buffers); } + virtqueue_fill(q->rx_vq, &head, head_len, 0); virtqueue_flush(q->rx_vq, i); virtio_notify(vdev, q->rx_vq); From patchwork Thu Oct 11 14:08:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982513 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WClK2jDwz9s4s for ; Fri, 12 Oct 2018 01:19:25 +1100 (AEDT) Received: from localhost ([::1]:34738 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAboA-0003vA-FB for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:19:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39451) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbek-00055V-6v for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbef-0006AB-8L for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56060) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbed-00065m-6i for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:33 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6490B99CEA; Thu, 11 Oct 2018 14:09:25 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3AEB95D73F; Thu, 11 Oct 2018 14:09:22 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:33 -0400 Message-Id: <1539266915-15216-11-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 11 Oct 2018 14:09:25 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 10/12] virtio: packed ring feature bit for userspace backend 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu Signed-off-by: Wei Xu --- hw/net/vhost_net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index e037db6..fb4b18f 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -78,6 +78,7 @@ static const int user_feature_bits[] = { VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_MTU, VIRTIO_F_IOMMU_PLATFORM, + VIRTIO_F_RING_PACKED, /* This bit implies RARP isn't sent by QEMU out of band */ VIRTIO_NET_F_GUEST_ANNOUNCE, From patchwork Thu Oct 11 14:08:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982506 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCcH1QMQz9s4s for ; Fri, 12 Oct 2018 01:13:19 +1100 (AEDT) Received: from localhost ([::1]:34702 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbiG-0007e8-MD for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:13:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39450) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbek-00055U-6o for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbef-00069q-4I for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45162) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeb-00067F-8e for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:31 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 15AE161476; Thu, 11 Oct 2018 14:09:28 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC5ED5D6A9; Thu, 11 Oct 2018 14:09:25 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:34 -0400 Message-Id: <1539266915-15216-12-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 11 Oct 2018 14:09:28 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 11/12] virtio: enable packed ring via a new command line 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu only userspace virtio net backend has been supported by the CLI so far. (cherry picked from commit 0b3ec96f4a9402cca467c40353066e57608ac6b6) Signed-off-by: Wei Xu (cherry picked from commit a1a3b85f00299ccc6f4bc819abe470da88059fb7) Signed-off-by: Wei Xu --- include/hw/virtio/virtio.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index e323e76..9af8839 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -264,7 +264,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, false) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); From patchwork Thu Oct 11 14:08:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Xu X-Patchwork-Id: 982510 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 DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WCgc228vz9s5b for ; Fri, 12 Oct 2018 01:16:12 +1100 (AEDT) Received: from localhost ([::1]:34721 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbl3-0001aC-Oc for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2018 10:16:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39455) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAbek-00055X-7u for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAbeh-0006E9-CC for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42240) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAbeh-00068W-3u for qemu-devel@nongnu.org; Thu, 11 Oct 2018 10:09:35 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B663E30041E9; Thu, 11 Oct 2018 14:09:30 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8D7FE5D791; Thu, 11 Oct 2018 14:09:28 +0000 (UTC) From: wexu@redhat.com To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2018 10:08:35 -0400 Message-Id: <1539266915-15216-13-git-send-email-wexu@redhat.com> In-Reply-To: <1539266915-15216-1-git-send-email-wexu@redhat.com> References: <1539266915-15216-1-git-send-email-wexu@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Thu, 11 Oct 2018 14:09:30 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [[RFC v3 12/12] virtio: feature vhost-net 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: , Cc: maxime.coquelin@redhat.com, jasowang@redhat.com, jfreimann@redhat.com, wexu@redhat.com, tiwei.bie@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wei Xu (cherry picked from commit 305a2c4640c15c5717245067ab937fd10f478ee6) Signed-off-by: Wei Xu (cherry picked from commit 46476dae6f44c6fef8802a4a0ac7d0d79fe399e3) Signed-off-by: Wei Xu --- hw/virtio/vhost.c | 3 +++ hw/virtio/virtio.c | 4 ++++ include/hw/virtio/virtio.h | 1 + 3 files changed, 8 insertions(+) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 9df2da3..de06d55 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -974,6 +974,9 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, } state.num = virtio_queue_get_last_avail_idx(vdev, idx); + if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) { + state.num |= ((int)virtio_queue_packed_get_wc(vdev, idx)) << 31; + } r = dev->vhost_ops->vhost_set_vring_base(dev, &state); if (r) { VHOST_OPS_DEBUG("vhost_set_vring_base failed"); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 1d25776..2a90163 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2894,6 +2894,10 @@ void virtio_init(VirtIODevice *vdev, const char *name, vdev->use_guest_notifier_mask = true; } +bool virtio_queue_packed_get_wc(VirtIODevice *vdev, int n) +{ + return vdev->vq[n].avail_wrap_counter; +} hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n) { return vdev->vq[n].vring.desc; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 9af8839..0bb3be5 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -295,6 +295,7 @@ void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx, VirtIOHandleAIOOutput handle_output); VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector); VirtQueue *virtio_vector_next_queue(VirtQueue *vq); +bool virtio_queue_packed_get_wc(VirtIODevice *vdev, int n); static inline void virtio_add_feature(uint64_t *features, unsigned int fbit) {