Author: bryanv
Date: Sun May  4 00:10:25 2014
New Revision: 265295
URL: http://svnweb.freebsd.org/changeset/base/265295

Log:
  MFC r255166, r255109:
  
   - Fix unintended compiler constant folding
   - Add support for postponing VirtIO virtqueue interrupts

Modified:
  stable/9/sys/dev/virtio/virtqueue.c
  stable/9/sys/dev/virtio/virtqueue.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/virtio/virtqueue.c
==============================================================================
--- stable/9/sys/dev/virtio/virtqueue.c Sun May  4 00:09:17 2014        
(r265294)
+++ stable/9/sys/dev/virtio/virtqueue.c Sun May  4 00:10:25 2014        
(r265295)
@@ -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 = ndesc / 4;
+               break;
+       case VQ_POSTPONE_LONG:
+               ndesc = (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: stable/9/sys/dev/virtio/virtqueue.h
==============================================================================
--- stable/9/sys/dev/virtio/virtqueue.h Sun May  4 00:09:17 2014        
(r265294)
+++ stable/9/sys/dev/virtio/virtqueue.h Sun May  4 00:10:25 2014        
(r265295)
@@ -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. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to