virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: virtualization@lists.linux-foundation.org
Subject: Re: [PATCH][RESEND] Relax BUG_ON()s when enabling/disabling virt_ring interrupts
Date: Mon, 7 Jan 2008 14:27:31 +1100	[thread overview]
Message-ID: <200801071427.31369.rusty@rustcorp.com.au> (raw)
In-Reply-To: <11995874312740-git-send-email-aliguori@us.ibm.com>

On Sunday 06 January 2008 13:43:51 Anthony Liguori wrote:
> Currently, the virt_ring->enable_cb and virt_ring->disable_cb functions
> enforce that they were called only when callbacks were disabled and enabled
> respectively.  However, in the current vring implementation, this isn't
> actually a bug.  What's more, the virtio_net driver does not guard against
> double enabling or double disabling.  All that needs to happen is for an rx
> notification to happen twice beforce the virtnet_poll function is invoked
> to trigger the BUG_ON.

BTW, my mailserver never received the this patch the first time.  Disturbing.

But this analysis isn't correct, AFAICT.  rx notification -> skb_recv_done
-> disable_cb.  So the second rx notification should not occur.  Certainly
that's a desirable semantic for virtio users (that disable disables).

Note, however, that the NO_INTERRUPT bit isn't synchronous: the host may be
about to deliver an interrupt and have missed the update.  This seems fair:
it's an optimization, not a hard requirement.  However, I'd prefer to fix
this by checking the bit in the actual interrupt handler, rather than
loosening the requirements which might catch real bugs.

I've managed to convince myself that no synchronization is needed here for
the case of SMP guests and the virtio_net driver (because disable_cb is
called from interrupt context, which have to be serialized so we don't
run the same interrupt handler for the same interrupt at the same time).

Concur?
Rusty.

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 <rusty@rustcorp.com.au>
---
 drivers/virtio/virtio_ring.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff -r 7aea9c3fcd6b drivers/virtio/virtio_ring.c
--- a/drivers/virtio/virtio_ring.c	Sat Jan 05 11:30:17 2008 +1100
+++ b/drivers/virtio/virtio_ring.c	Mon Jan 07 11:39:46 2008 +1100
@@ -265,6 +265,13 @@ irqreturn_t vring_interrupt(int irq, voi
 	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);

  reply	other threads:[~2008-01-07  3:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-06  2:43 [PATCH][RESEND] Relax BUG_ON()s when enabling/disabling virt_ring interrupts Anthony Liguori
2008-01-07  3:27 ` Rusty Russell [this message]
2008-01-07  4:29   ` Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200801071427.31369.rusty@rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=aliguori@us.ibm.com \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).