From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dor Laor Subject: Re: [PATCH 2/3] virtio ring implementation Date: Mon, 24 Sep 2007 15:44:33 +0200 Message-ID: <46F7BF41.9060705@qumranet.com> References: <1190625194.27805.199.camel@localhost.localdomain><1190625256.27805.201.camel@localhost.localdomain> <1190625307.27805.203.camel@localhost.localdomain> Reply-To: dor.laor-atKUWr5tajBWk0Htik3J/w@public.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0365509113==" Cc: kvm-devel , virtualization To: Rusty Russell Return-path: In-Reply-To: <1190625307.27805.203.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org This is a multi-part message in MIME format. --===============0365509113== Content-Type: multipart/alternative; boundary="------------060203060201060203030304" This is a multi-part message in MIME format. --------------060203060201060203030304 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Rusty Russell wrote: > > These helper routines supply most of the virtqueue_ops for hypervisors > which want to use a ring for virtio. Unlike the previous lguest > implementation: > > 1) The rings are variable sized (2^n-1 elements). > 2) They have an unfortunate limit of 65535 bytes per sg element. > 3) The page numbers are always 64 bit (PAE anyone?) > 4) They no longer place used[] on a separate page, just a separate > cacheline. > 5) We do a modulo on a variable. We could be tricky if we cared. > 6) Interrupts and notifies are suppressed using flags within the rings. > > Users need only implement the new_vq and free_vq hooks (KVM wants the > guest to allocate the rings, lguest does it sanely). > > Signed-off-by: Rusty Russell > [snip] > > +irqreturn_t vring_interrupt(int irq, void *_vq) > +{ > + struct vring_virtqueue *vq = to_vvq(_vq); > + > + pr_debug("virtqueue interrupt for %p\n", vq); > + > + if (unlikely(vq->broken)) > + return IRQ_HANDLED; > + > + if (more_used(vq)) { > + pr_debug("virtqueue callback for %p (%p)\n", > + vq, vq->vq.callback); > + if (!vq->vq.callback) > + return IRQ_NONE; > + if (!vq->vq.callback(&vq->vq)) > + vq->vring.avail->flags |= > VRING_AVAIL_F_NO_INTERRUPT; > + } else > + pr_debug("virtqueue %p no more used\n", vq); > + > + return IRQ_HANDLED; > +} > + > Seems like there is a problem with shared irq line, the interrupt handler always returns IRQ_HANDLED (except for the trivial case were the callback is null). It can be solved by having a host irq counter (in the shared ring) and a guest irq counter and return mb(); return (host_counter!=guest_counter)? IRQ_HANDLED:IRQ_NONE; Dor. --------------060203060201060203030304 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Rusty Russell wrote:
[kvm-devel] [PATCH 2/3] virtio ring implementation

These helper routines supply most of the virtqueue_ops for hypervisors
which want to use a ring for virtio.  Unlike the previous lguest
implementation:

1) The rings are variable sized (2^n-1 elements).
2) They have an unfortunate limit of 65535 bytes per sg element.
3) The page numbers are always 64 bit (PAE anyone?)
4) They no longer place used[] on a separate page, just a separate
   cacheline.
5) We do a modulo on a variable.  We could be tricky if we cared.
6) Interrupts and notifies are suppressed using flags within the rings.

Users need only implement the new_vq and free_vq hooks (KVM wants the
guest to allocate the rings, lguest does it sanely).

Signed-off-by: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>

[snip]

+irqreturn_t vring_interrupt(int irq, void *_vq)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+
+       pr_debug("virtqueue interrupt for %p\n", vq);
+
+       if (unlikely(vq->broken))
+               return IRQ_HANDLED;
+
+       if (more_used(vq)) {
+               pr_debug("virtqueue callback for %p (%p)\n",
+                        vq, vq->vq.callback);
+               if (!vq->vq.callback)
+                       return IRQ_NONE;
+               if (!vq->vq.callback(&vq->vq))
+                       vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+       } else
+               pr_debug("virtqueue %p no more used\n", vq);
+
+       return IRQ_HANDLED;
+}
+

Seems like there is a problem with shared irq line, the interrupt handler always returns IRQ_HANDLED (except for the trivial case
were the callback is null).

It can be solved by having a host irq counter (in the shared ring) and a guest irq counter and return
mb(); return (host_counter!=guest_counter)? IRQ_HANDLED:IRQ_NONE;

Dor.
--------------060203060201060203030304-- --===============0365509113== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ --===============0365509113== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --===============0365509113==--