summaryrefslogtreecommitdiff
path: root/Documentation/lguest/lguest.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r--Documentation/lguest/lguest.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 5470b8ed2149..84c471b07c27 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -551,6 +551,21 @@ static unsigned next_desc(struct virtqueue *vq, unsigned int i)
return next;
}
+/* This actually sends the interrupt for this virtqueue */
+static void trigger_irq(struct virtqueue *vq)
+{
+ unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+
+ /* 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)
+ return;
+
+ /* Send the Guest an interrupt tell them we used something up. */
+ if (write(lguest_fd, buf, sizeof(buf)) != 0)
+ err(1, "Triggering irq %i", vq->config.irq);
+}
+
/* This looks in the virtqueue and for the first available buffer, and converts
* it to an iovec for convenient access. Since descriptors consist of some
* number of output then some number of input descriptors, it's actually two
@@ -567,6 +582,9 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
while (last_avail == vq->vring.avail->idx) {
u64 event;
+ /* OK, tell Guest about progress up to now. */
+ trigger_irq(vq);
+
/* Nothing new? Wait for eventfd to tell us they refilled. */
if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
errx(1, "Event read failed?");
@@ -631,21 +649,6 @@ static void add_used(struct virtqueue *vq, unsigned int head, int len)
vq->vring.used->idx++;
}
-/* This actually sends the interrupt for this virtqueue */
-static void trigger_irq(struct virtqueue *vq)
-{
- unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
-
- /* 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)
- return;
-
- /* Send the Guest an interrupt tell them we used something up. */
- if (write(lguest_fd, buf, sizeof(buf)) != 0)
- err(1, "Triggering irq %i", vq->config.irq);
-}
-
/* And here's the combo meal deal. Supersize me! */
static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len)
{
@@ -730,7 +733,7 @@ static void console_output(struct virtqueue *vq)
err(1, "Write to stdout gave %i", len);
iov_consume(iov, out, len);
}
- add_used_and_trigger(vq, head, 0);
+ add_used(vq, head, 0);
}
/*
@@ -754,7 +757,7 @@ static void net_output(struct virtqueue *vq)
errx(1, "Input buffers in net output queue?");
if (writev(net_info->tunfd, iov, out) < 0)
errx(1, "Write to tun failed?");
- add_used_and_trigger(vq, head, 0);
+ add_used(vq, head, 0);
}
/* This is where we handle packets coming in from the tun device to our
@@ -1422,7 +1425,7 @@ static void blk_request(struct virtqueue *vq)
if (out->type & VIRTIO_BLK_T_BARRIER)
fdatasync(vblk->fd);
- add_used_and_trigger(vq, head, wlen);
+ add_used(vq, head, wlen);
}
/*L:198 This actually sets up a virtual block device. */
@@ -1496,7 +1499,7 @@ static void rng_input(struct virtqueue *vq)
}
/* Tell the Guest about the new input. */
- add_used_and_trigger(vq, head, totlen);
+ add_used(vq, head, totlen);
}
/* And this creates a "hardware" random number device for the Guest. */