Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753331Ab1EEJgO (ORCPT ); Thu, 5 May 2011 05:36:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53767 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751262Ab1EEJgM (ORCPT ); Thu, 5 May 2011 05:36:12 -0400 Date: Thu, 5 May 2011 12:34:58 +0300 From: "Michael S. Tsirkin" To: Tom Lendacky Cc: linux-kernel@vger.kernel.org, Rusty Russell , Carsten Otte , Christian Borntraeger , linux390@de.ibm.com, Martin Schwidefsky , Heiko Carstens , Shirley Ma , lguest@lists.ozlabs.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-s390@vger.kernel.org, kvm@vger.kernel.org, Krishna Kumar , steved@us.ibm.com, habanero@linux.vnet.ibm.com Subject: Re: [PATCH 09/18] virtio: use avail_event index Message-ID: <20110505093458.GD28378@redhat.com> References: <8bba6a0a8eee17e741c5155b04ff1b1c9f34bf94.1304541919.git.mst@redhat.com> <201105041658.19917.tahm@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <201105041658.19917.tahm@linux.vnet.ibm.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3936 Lines: 116 On Wed, May 04, 2011 at 04:58:18PM -0500, Tom Lendacky wrote: > > On Wednesday, May 04, 2011 03:51:47 PM Michael S. Tsirkin wrote: > > Use the new avail_event feature to reduce the number > > of exits from the guest. > > > > Signed-off-by: Michael S. Tsirkin > > --- > > drivers/virtio/virtio_ring.c | 39 > > ++++++++++++++++++++++++++++++++++++++- 1 files changed, 38 insertions(+), > > 1 deletions(-) > > > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > > index 3a3ed75..262dfe6 100644 > > --- a/drivers/virtio/virtio_ring.c > > +++ b/drivers/virtio/virtio_ring.c > > @@ -82,6 +82,15 @@ struct vring_virtqueue > > /* Host supports indirect buffers */ > > bool indirect; > > > > + /* Host publishes avail event idx */ > > + bool event; > > + > > + /* Is kicked_avail below valid? */ > > + bool kicked_avail_valid; > > + > > + /* avail idx value we already kicked. */ > > + u16 kicked_avail; > > + > > /* Number of free buffers */ > > unsigned int num_free; > > /* Head of free buffer list. */ > > @@ -228,6 +237,12 @@ add_head: > > * new available array entries. */ > > virtio_wmb(); > > vq->vring.avail->idx++; > > + /* If the driver never bothers to kick in a very long while, > > + * avail index might wrap around. If that happens, invalidate > > + * kicked_avail index we stored. TODO: make sure all drivers > > + * kick at least once in 2^16 and remove this. */ > > + if (unlikely(vq->vring.avail->idx == vq->kicked_avail)) > > + vq->kicked_avail_valid = true; > > vq->kicked_avail_valid should be set to false here. > > Tom Right, good catch. > > > > pr_debug("Added buffer head %i to %p\n", head, vq); > > END_USE(vq); > > @@ -236,6 +251,23 @@ add_head: > > } > > EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); > > > > + > > +static bool vring_notify(struct vring_virtqueue *vq) > > +{ > > + u16 old, new; > > + bool v; > > + if (!vq->event) > > + return !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY); > > + > > + v = vq->kicked_avail_valid; > > + old = vq->kicked_avail; > > + new = vq->kicked_avail = vq->vring.avail->idx; > > + vq->kicked_avail_valid = true; > > + if (unlikely(!v)) > > + return true; > > + return vring_need_event(vring_avail_event(&vq->vring), new, old); > > +} > > + > > void virtqueue_kick(struct virtqueue *_vq) > > { > > struct vring_virtqueue *vq = to_vvq(_vq); > > @@ -244,7 +276,7 @@ void virtqueue_kick(struct virtqueue *_vq) > > /* Need to update avail index before checking if we should notify */ > > virtio_mb(); > > > > - if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) > > + if (vring_notify(vq)) > > /* Prod other side to tell it about changes. */ > > vq->notify(&vq->vq); > > > > @@ -437,6 +469,8 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, > > vq->vq.name = name; > > vq->notify = notify; > > vq->broken = false; > > + vq->kicked_avail_valid = false; > > + vq->kicked_avail = 0; > > vq->last_used_idx = 0; > > list_add_tail(&vq->vq.list, &vdev->vqs); > > #ifdef DEBUG > > @@ -444,6 +478,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, > > #endif > > > > vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC); > > + vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_AVAIL_EVENT_IDX); > > > > /* No callback? Tell other side not to bother us. */ > > if (!callback) > > @@ -482,6 +517,8 @@ void vring_transport_features(struct virtio_device > > *vdev) break; > > case VIRTIO_RING_F_USED_EVENT_IDX: > > break; > > + case VIRTIO_RING_F_AVAIL_EVENT_IDX: > > + break; > > default: > > /* We don't understand this bit. */ > > clear_bit(i, vdev->features); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/