If we track how many buffers we've used, we can tell whether we really
need to interrupt the Guest. This happens as a side effect of
spurious notifications.
Spurious notifications happen because it can take a while before the
Host thread wakes up and sets the VRING_USED_F_NO_NOTIFY flag, and
meanwhile the Guest can more notifications.
A real fix would be to use wake counts, rather than a suppression
flag, but the practical difference is generally in the noise: the
interrupt is usually coalesced into a pending one anyway so we just
save a system call which isn't clearly measurable.
Secs Spurious IRQS
1G TCP Guest->Host: 3.93 58
1M normal pings: 100 72
1M 1k pings (-l 120): 57 492904
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
/* Last available index we saw. */
u16 last_avail_idx;
+ /* How many are used since we sent last irq? */
+ unsigned int pending_used;
+
/* Eventfd where Guest notifications arrive. */
int eventfd;
{
unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+ /* Don't inform them if nothing used. */
+ if (!vq->pending_used)
+ return;
+ vq->pending_used = 0;
+
/* If they don't want an interrupt, don't send one, unless empty. */
if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
&& lg_last_avail(vq) != vq->vring.avail->idx)
/* Make sure buffer is written before we update index. */
wmb();
vq->vring.used->idx++;
+ vq->pending_used++;
}
/* And here's the combo meal deal. Supersize me! */