diff options
Diffstat (limited to 'sys/dev/virtio/virtqueue.c')
-rw-r--r-- | sys/dev/virtio/virtqueue.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/sys/dev/virtio/virtqueue.c b/sys/dev/virtio/virtqueue.c index a82426ea1b49..beff14c5ab7a 100644 --- a/sys/dev/virtio/virtqueue.c +++ b/sys/dev/virtio/virtqueue.c @@ -127,7 +127,7 @@ static uint16_t vq_ring_enqueue_segments(struct virtqueue *, static int vq_ring_use_indirect(struct virtqueue *, int); static void vq_ring_enqueue_indirect(struct virtqueue *, void *, struct sglist *, int, int); -static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t); +static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t); static int vq_ring_must_notify_host(struct virtqueue *); static void vq_ring_notify_host(struct virtqueue *); static void vq_ring_free_chain(struct virtqueue *, uint16_t); @@ -440,28 +440,38 @@ virtqueue_enable_intr(struct virtqueue *vq) } int -virtqueue_postpone_intr(struct virtqueue *vq) +virtqueue_postpone_intr(struct virtqueue *vq, vq_postpone_t hint) { uint16_t ndesc, avail_idx; - /* - * Request the next interrupt be postponed until at least half - * of the available descriptors have been consumed. - */ avail_idx = vq->vq_ring.avail->idx; - ndesc = (uint16_t)(avail_idx - vq->vq_used_cons_idx) / 2; + ndesc = (uint16_t)(avail_idx - vq->vq_used_cons_idx); + + switch (hint) { + case VQ_POSTPONE_SHORT: + ndesc /= 4; + break; + case VQ_POSTPONE_LONG: + ndesc *= 3 / 4; + break; + case VQ_POSTPONE_EMPTIED: + break; + } return (vq_ring_enable_interrupt(vq, ndesc)); } +/* + * Note this is only considered a hint to the host. + */ void virtqueue_disable_intr(struct virtqueue *vq) { - /* - * Note this is only considered a hint to the host. - */ - if ((vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) == 0) + if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) { + vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx - + vq->vq_nentries - 1; + } else vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; } |