From patchwork Wed May 4 21:02:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 94164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 632C41007DB for ; Thu, 5 May 2011 07:03:37 +1000 (EST) Received: from localhost ([::1]:40270 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QHjEM-0004RD-PS for incoming@patchwork.ozlabs.org; Wed, 04 May 2011 17:03:34 -0400 Received: from eggs.gnu.org ([140.186.70.92]:59593) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QHjE5-0004No-HI for qemu-devel@nongnu.org; Wed, 04 May 2011 17:03:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QHjE3-0007EZ-Cp for qemu-devel@nongnu.org; Wed, 04 May 2011 17:03:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:20925) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QHjE2-0007E7-H9 for qemu-devel@nongnu.org; Wed, 04 May 2011 17:03:15 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p44L2Vt8004934 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 4 May 2011 17:02:31 -0400 Received: from redhat.com (vpn-201-69.tlv.redhat.com [10.35.201.69]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id p44L2Pr1000783; Wed, 4 May 2011 17:02:26 -0400 Date: Thu, 5 May 2011 00:02:15 +0300 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Message-ID: <920d6df05a935ddcae23c3213cc9d2da0bf1c413.1304542880.git.mst@redhat.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Mutt-Fcc: =sent User-Agent: Mutt/1.5.21 (2010-09-15) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Krishna Kumar , Carsten Otte , lguest@lists.ozlabs.org, Shirley Ma , kvm@vger.kernel.org, linux-s390@vger.kernel.org, habanero@linux.vnet.ibm.com, Rusty Russell , Heiko Carstens , virtualization@lists.linux-foundation.org, steved@us.ibm.com, Christian Borntraeger , Tom Lendacky , Martin Schwidefsky , linux390@de.ibm.com Subject: [Qemu-devel] [PATCH 3/3] virtio: avail_event index support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 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-bounces+incoming=patchwork.ozlabs.org@nongnu.org Reduce the number of exits utilizing the avail_event feature. Signed-off-by: Michael S. Tsirkin --- hw/vhost_net.c | 6 ++++++ hw/virtio.c | 26 ++++++++++++++++++++++++-- hw/virtio.h | 7 ++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/hw/vhost_net.c b/hw/vhost_net.c index 18e4653..aeb5a84 100644 --- a/hw/vhost_net.c +++ b/hw/vhost_net.c @@ -53,6 +53,9 @@ uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features) if (!(net->dev.features & (1ULL << VIRTIO_RING_F_USED_EVENT_IDX))) { features &= ~(1ULL << VIRTIO_RING_F_USED_EVENT_IDX); } + if (!(net->dev.features & (1ULL << VIRTIO_RING_F_AVAIL_EVENT_IDX))) { + features &= ~(1ULL << VIRTIO_RING_F_AVAIL_EVENT_IDX); + } if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) { features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF); } @@ -71,6 +74,9 @@ void vhost_net_ack_features(struct vhost_net *net, uint64_t features) if (features & (1ULL << VIRTIO_RING_F_USED_EVENT_IDX)) { net->dev.acked_features |= (1ULL << VIRTIO_RING_F_USED_EVENT_IDX); } + if (features & (1ULL << VIRTIO_RING_F_AVAIL_EVENT_IDX)) { + net->dev.acked_features |= (1ULL << VIRTIO_RING_F_AVAIL_EVENT_IDX); + } if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF); } diff --git a/hw/virtio.c b/hw/virtio.c index e459093..6ae5542 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -78,6 +78,9 @@ struct VirtQueue /* Last used index value we have signalled on */ bool signalled_used_valid; + /* Notification enabled? */ + bool notification; + int inuse; uint16_t vector; @@ -195,12 +198,26 @@ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask) stw_phys(pa, lduw_phys(pa) & ~mask); } +static inline void vring_avail_event(VirtQueue *vq, uint16_t val) +{ + target_phys_addr_t pa; + if (!vq->notification) { + return; + } + pa = vq->vring.used + offsetof(VRingUsed, ring[vq->vring.num]); + stw_phys(pa, val); +} + void virtio_queue_set_notification(VirtQueue *vq, int enable) { - if (enable) + vq->notification = enable; + if (vq->vdev->guest_features & (1ULL << VIRTIO_RING_F_AVAIL_EVENT_IDX)) { + vring_avail_event(vq, vq->last_avail_idx); + } else if (enable) { vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY); - else + } else { vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY); + } } int virtio_queue_ready(VirtQueue *vq) @@ -412,6 +429,9 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) max = vq->vring.num; i = head = virtqueue_get_head(vq, vq->last_avail_idx++); + if (vq->vdev->guest_features & (1ULL << VIRTIO_RING_F_AVAIL_EVENT_IDX)) { + vring_avail_event(vq, vq->last_avail_idx); + } if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) { if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) { @@ -497,6 +517,7 @@ void virtio_reset(void *opaque) vdev->vq[i].vector = VIRTIO_NO_VECTOR; vdev->vq[i].signalled_used = 0; vdev->vq[i].signalled_used_valid = false; + vdev->vq[i].notification = true; } } @@ -784,6 +805,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) vdev->vq[i].pa = qemu_get_be64(f); qemu_get_be16s(f, &vdev->vq[i].last_avail_idx); vdev->vq[i].signalled_used_valid = false; + vdev->vq[i].notification = true; if (vdev->vq[i].pa) { uint16_t nheads; diff --git a/hw/virtio.h b/hw/virtio.h index d765946..8c0923a 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -54,6 +54,9 @@ /* Enables feature bits 32 to 63 (only really required for virtio_pci). */ #define VIRTIO_F_FEATURES_HI 31 +/* The Host publishes the avail index for which it expects a kick + * at the end of the used ring. Guest should ignore the used->flags field. */ +#define VIRTIO_RING_F_AVAIL_EVENT_IDX 32 /* from Linux's linux/virtio_ring.h */ @@ -218,7 +221,9 @@ void virtio_serial_exit(VirtIODevice *vdev); DEFINE_PROP_BIT64("indirect_desc", _state, _field, \ VIRTIO_RING_F_INDIRECT_DESC, true), \ DEFINE_PROP_BIT64("used_event", _state, _field, \ - VIRTIO_RING_F_USED_EVENT_IDX, true) + VIRTIO_RING_F_USED_EVENT_IDX, true), \ + DEFINE_PROP_BIT64("avail_event", _state, _field, \ + VIRTIO_RING_F_AVAIL_EVENT_IDX, true) target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);