The Guest only really needs to tell us about activity when we're going
to listen to the eventfd: normally, we don't want to know.
So if there are no available buffers, turn on notifications, re-check,
then wait for the Guest to notify us via the eventfd, then turn
notifications off again.
There's enough else going on that the differences are in the noise.
Before: Secs RxKicks TxKicks
1G TCP Guest->Host: 3.94 4686 32815
1M normal pings: 104 142862 1000010
1M 1k pings (-l 120): 57 142026 1000007
After:
1G TCP Guest->Host: 3.76 4691 32811
1M normal pings: 111 142859 997467
1M 1k pings (-l 120): 55 19648 501549
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
* threads and so we need to make sure that changes visible to the Guest happen
* in precise order. */
#define wmb() __asm__ __volatile__("" : : : "memory")
* threads and so we need to make sure that changes visible to the Guest happen
* in precise order. */
#define wmb() __asm__ __volatile__("" : : : "memory")
+#define mb() __asm__ __volatile__("" : : : "memory")
/* Convert an iovec element to the given type.
*
/* Convert an iovec element to the given type.
*
/* OK, tell Guest about progress up to now. */
trigger_irq(vq);
/* OK, tell Guest about progress up to now. */
trigger_irq(vq);
+ /* OK, now we need to know about added descriptors. */
+ vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+
+ /* They could have slipped one in as we were doing that: make
+ * sure it's written, then check again. */
+ mb();
+ if (last_avail != vq->vring.avail->idx) {
+ vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+ break;
+ }
+
/* Nothing new? Wait for eventfd to tell us they refilled. */
if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
errx(1, "Event read failed?");
/* Nothing new? Wait for eventfd to tell us they refilled. */
if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
errx(1, "Event read failed?");
+
+ /* We don't need to be notified again. */
+ vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
}
/* Check it isn't doing very strange things with descriptor numbers. */
}
/* Check it isn't doing very strange things with descriptor numbers. */