20887611523e749d99cc7d64ff6c97d27529fbae (lguest: notify on empty) introduced
lguest support for the VIRTIO_F_NOTIFY_ON_EMPTY flag, but in fact it turned on
interrupts all the time.
Because we always process one buffer at a time, the inflight count is always 0
when call trigger_irq and so we always ignore VRING_AVAIL_F_NO_INTERRUPT from
the Guest.
It should be looking to see if there are more buffers in the Guest's queue:
if it's empty, then we force an interrupt.
This makes little difference, since we usually have an empty queue; but
that's the subject of another patch.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
/* The routine to call when the Guest pings us, or timeout. */
void (*handle_output)(struct virtqueue *me, bool timeout);
/* The routine to call when the Guest pings us, or timeout. */
void (*handle_output)(struct virtqueue *me, bool timeout);
- /* Outstanding buffers */
- unsigned int inflight;
-
/* Is this blocked awaiting a timer? */
bool blocked;
};
/* Is this blocked awaiting a timer? */
bool blocked;
};
errx(1, "Looped descriptor");
} while ((i = next_desc(vq, i)) != vq->vring.num);
errx(1, "Looped descriptor");
} while ((i = next_desc(vq, i)) != vq->vring.num);
/* Make sure buffer is written before we update index. */
wmb();
vq->vring.used->idx++;
/* Make sure buffer is written before we update index. */
wmb();
vq->vring.used->idx++;
}
/* This actually sends the interrupt for this virtqueue */
}
/* This actually sends the interrupt for this virtqueue */
/* If they don't want an interrupt, don't send one, unless empty. */
if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
/* 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. */
return;
/* Send the Guest an interrupt tell them we used something up. */
vq->next = NULL;
vq->last_avail_idx = 0;
vq->dev = dev;
vq->next = NULL;
vq->last_avail_idx = 0;
vq->dev = dev;
vq->blocked = false;
/* Initialize the configuration. */
vq->blocked = false;
/* Initialize the configuration. */