aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-09-24 00:26:47 -0400
committerRusty Russell <rusty@rustcorp.com.au>2009-09-23 08:56:47 -0400
commitca60a42c9be41c07ebcc2ec8c43dd1be53f147bf (patch)
treeca7ef0c06dc20d0529c9c2edfb22a2925edeb721
parent6c189d8312246af776c2587c233d6afcf3714438 (diff)
lguest: don't force VIRTIO_F_NOTIFY_ON_EMPTY
VIRTIO_F_NOTIFY_ON_EMPTY indicates to the Guest that we will hit them with an interrupt every time the xmit queue is emptied. Because it results in lots of tx interrupts, modern Guests probably don't want it, so let's only force it when they accept the option. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--Documentation/lguest/lguest.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 84bbb190bf7b..ba9373f82ab5 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -134,6 +134,9 @@ struct device {
134 /* Is it operational */ 134 /* Is it operational */
135 bool running; 135 bool running;
136 136
137 /* Does Guest want an intrrupt on empty? */
138 bool irq_on_empty;
139
137 /* Device-specific data. */ 140 /* Device-specific data. */
138 void *priv; 141 void *priv;
139}; 142};
@@ -624,10 +627,13 @@ static void trigger_irq(struct virtqueue *vq)
624 return; 627 return;
625 vq->pending_used = 0; 628 vq->pending_used = 0;
626 629
627 /* If they don't want an interrupt, don't send one, unless empty. */ 630 /* If they don't want an interrupt, don't send one... */
628 if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) 631 if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
629 && lg_last_avail(vq) != vq->vring.avail->idx) 632 /* ... unless they've asked us to force one on empty. */
630 return; 633 if (!vq->dev->irq_on_empty
634 || lg_last_avail(vq) != vq->vring.avail->idx)
635 return;
636 }
631 637
632 /* Send the Guest an interrupt tell them we used something up. */ 638 /* Send the Guest an interrupt tell them we used something up. */
633 if (write(lguest_fd, buf, sizeof(buf)) != 0) 639 if (write(lguest_fd, buf, sizeof(buf)) != 0)
@@ -1043,6 +1049,15 @@ static void create_thread(struct virtqueue *vq)
1043 close(vq->eventfd); 1049 close(vq->eventfd);
1044} 1050}
1045 1051
1052static bool accepted_feature(struct device *dev, unsigned int bit)
1053{
1054 const u8 *features = get_feature_bits(dev) + dev->feature_len;
1055
1056 if (dev->feature_len < bit / CHAR_BIT)
1057 return false;
1058 return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT));
1059}
1060
1046static void start_device(struct device *dev) 1061static void start_device(struct device *dev)
1047{ 1062{
1048 unsigned int i; 1063 unsigned int i;
@@ -1056,6 +1071,8 @@ static void start_device(struct device *dev)
1056 verbose(" %02x", get_feature_bits(dev) 1071 verbose(" %02x", get_feature_bits(dev)
1057 [dev->feature_len+i]); 1072 [dev->feature_len+i]);
1058 1073
1074 dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
1075
1059 for (vq = dev->vq; vq; vq = vq->next) { 1076 for (vq = dev->vq; vq; vq = vq->next) {
1060 if (vq->service) 1077 if (vq->service)
1061 create_thread(vq); 1078 create_thread(vq);