Date: Sun, 19 May 2013 03:01:34 +0000 (UTC) From: Bryan Venteicher <bryanv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r250801 - in user/bryanv/vtnetmq/sys/dev/virtio: . network Message-ID: <201305190301.r4J31YsG055715@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bryanv Date: Sun May 19 03:01:33 2013 New Revision: 250801 URL: http://svnweb.freebsd.org/changeset/base/250801 Log: Add support for the EVENT_IDX feature to the network driver This allows the driver to defer the Tx completion interrupt. Modified: user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.c user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.h Modified: user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c Sun May 19 02:58:04 2013 (r250800) +++ user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c Sun May 19 03:01:33 2013 (r250801) @@ -3671,6 +3671,7 @@ static int vtnet_txq_enable_intr(struct vtnet_txq *txq) { + return (virtqueue_postpone_intr(txq->vtntx_vq, VQ_POSTPONE_LONG)); return (virtqueue_enable_intr(txq->vtntx_vq)); } Modified: user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.c ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.c Sun May 19 02:58:04 2013 (r250800) +++ user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.c Sun May 19 03:01:33 2013 (r250801) @@ -127,7 +127,7 @@ static uint16_t vq_ring_enqueue_segments 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 * } 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; } Modified: user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.h ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.h Sun May 19 02:58:04 2013 (r250800) +++ user/bryanv/vtnetmq/sys/dev/virtio/virtqueue.h Sun May 19 03:01:33 2013 (r250801) @@ -41,6 +41,16 @@ struct sglist; /* Device callback for a virtqueue interrupt. */ typedef void virtqueue_intr_t(void *); +/* + * Hint on how long the next interrupt should be postponed. This is + * only used when the EVENT_IDX feature is negotiated. + */ +typedef enum { + VQ_POSTPONE_SHORT, + VQ_POSTPONE_LONG, + VQ_POSTPONE_EMPTIED /* Until all available desc are used. */ +} vq_postpone_t; + #define VIRTQUEUE_MAX_NAME_SZ 32 /* One for each virtqueue the device wishes to allocate. */ @@ -73,7 +83,7 @@ int virtqueue_reinit(struct virtqueue * int virtqueue_intr_filter(struct virtqueue *vq); void virtqueue_intr(struct virtqueue *vq); int virtqueue_enable_intr(struct virtqueue *vq); -int virtqueue_postpone_intr(struct virtqueue *vq); +int virtqueue_postpone_intr(struct virtqueue *vq, vq_postpone_t hint); void virtqueue_disable_intr(struct virtqueue *vq); /* Get physical address of the virtqueue ring. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305190301.r4J31YsG055715>