svn commit: r250801 - in user/bryanv/vtnetmq/sys/dev/virtio: . network
Bryan Venteicher
bryanv at FreeBSD.org
Sun May 19 03:01:34 UTC 2013
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. */
More information about the svn-src-user
mailing list