Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=81a8deab1ce3816c6a89e3429e234e7d3686da94
Commit:     81a8deab1ce3816c6a89e3429e234e7d3686da94
Parent:     6e5aa7efb27aec7e55b6463fa2c8db594c4226fa
Author:     Rusty Russell <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 4 23:50:04 2008 -0500
Committer:  Rusty Russell <[EMAIL PROTECTED]>
CommitDate: Mon Feb 4 23:50:04 2008 +1100

    virtio: handle interrupts after callbacks turned off
    
    Anthony Liguori found double interrupt suppression in the virtio_net
    driver, triggered by two skb_recv_done's in a row.  This is because
    virtio_ring's interrupt suppression is a best-effort optimization: it
    contains no synchronization so the host can miss it and still send
    interrupts.
    
    But it's certainly nicer for virtio users if calling disable_cb
    actually disables callbacks, so we check for the race in the interrupt
    routine.
    
    Note: SMP guests might require syncronization here, but since
    disable_cb is actually called from interrupt context, there has to be
    some form of synchronization before the next same interrupt handler is
    called (Linux guarantees that the same device's irq handler will never
    run simultanously on multiple CPUs).
    
    Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/virtio/virtio_ring.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 9849bab..9859213 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -255,6 +255,13 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
        if (unlikely(vq->broken))
                return IRQ_HANDLED;
 
+       /* Other side may have missed us turning off the interrupt,
+        * but we should preserve disable semantic for virtio users. */
+       if (unlikely(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) {
+               pr_debug("virtqueue interrupt after disable for %p\n", vq);
+               return IRQ_HANDLED;
+       }
+
        pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback);
        if (vq->vq.callback)
                vq->vq.callback(&vq->vq);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to