aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/lguest
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-06-13 00:27:11 -0400
committerRusty Russell <rusty@rustcorp.com.au>2009-06-12 08:57:12 -0400
commit95c517c09bad31a03e22f2fdb5f0aa26a490a92d (patch)
treeaa34fdb7ca3a6b7575a2ac7639c157995d334bc3 /Documentation/lguest
parent38bc2b8c56a2e212bbd19de7cf9976dcc7bf9953 (diff)
lguest: avoid sending interrupts to Guest when no activity occurs.
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>
Diffstat (limited to 'Documentation/lguest')
-rw-r--r--Documentation/lguest/lguest.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 84c471b07c27..20f8253881b3 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -151,6 +151,9 @@ struct virtqueue
151 /* Last available index we saw. */ 151 /* Last available index we saw. */
152 u16 last_avail_idx; 152 u16 last_avail_idx;
153 153
154 /* How many are used since we sent last irq? */
155 unsigned int pending_used;
156
154 /* Eventfd where Guest notifications arrive. */ 157 /* Eventfd where Guest notifications arrive. */
155 int eventfd; 158 int eventfd;
156 159
@@ -556,6 +559,11 @@ static void trigger_irq(struct virtqueue *vq)
556{ 559{
557 unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; 560 unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
558 561
562 /* Don't inform them if nothing used. */
563 if (!vq->pending_used)
564 return;
565 vq->pending_used = 0;
566
559 /* If they don't want an interrupt, don't send one, unless empty. */ 567 /* If they don't want an interrupt, don't send one, unless empty. */
560 if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) 568 if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
561 && lg_last_avail(vq) != vq->vring.avail->idx) 569 && lg_last_avail(vq) != vq->vring.avail->idx)
@@ -647,6 +655,7 @@ static void add_used(struct virtqueue *vq, unsigned int head, int len)
647 /* Make sure buffer is written before we update index. */ 655 /* Make sure buffer is written before we update index. */
648 wmb(); 656 wmb();
649 vq->vring.used->idx++; 657 vq->vring.used->idx++;
658 vq->pending_used++;
650} 659}
651 660
652/* And here's the combo meal deal. Supersize me! */ 661/* And here's the combo meal deal. Supersize me! */