On Thu, Dec 13, 2018 at 05:09:03PM +0100, Maxime Coquelin wrote:


On 12/13/18 1:34 PM, Jens Freimann wrote:
Add helper functions to set/clear and check descriptor flags.

Signed-off-by: Jens Freimann <jfreim...@redhat.com>
---
 drivers/net/virtio/virtqueue.h | 72 +++++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 1401a9844..b7a5a5963 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -250,6 +250,32 @@ struct virtio_tx_region {
                           __attribute__((__aligned__(16)));
 };
+static inline void
+_set_desc_avail(struct vring_packed_desc *desc, int wrap_counter)
+{
+       desc->flags |= VRING_DESC_F_AVAIL(wrap_counter) |
+                      VRING_DESC_F_USED(!wrap_counter);
+}
+
+static inline void
+set_desc_avail(struct virtqueue *vq, struct vring_packed_desc *desc)
+{
+       _set_desc_avail(desc, vq->avail_wrap_counter);
+}
+
+static inline int
+desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
+{
+       uint16_t used, avail, flags;
+
+       flags = desc->flags;
+       used = !!(flags & VRING_DESC_F_USED(1));
+       avail = !!(flags & VRING_DESC_F_AVAIL(1));
+
+       return avail == used && used == vq->used_wrap_counter;
+}
+
+
 static inline void
 vring_desc_init_packed(struct virtqueue *vq, int n)
 {
@@ -273,22 +299,64 @@ vring_desc_init_split(struct vring_desc *dp, uint16_t n)
        dp[i].next = VQ_RING_DESC_CHAIN_END;
 }
+/**
+ * Tell the backend not to interrupt us.
+ */
+static inline void
+virtqueue_disable_intr_packed(struct virtqueue *vq)
+{
+       uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
+
+       if (*event_flags != RING_EVENT_FLAGS_DISABLE) {
+               *event_flags = RING_EVENT_FLAGS_DISABLE;
+       }
+}
+
+
 /**
  * Tell the backend not to interrupt us.
  */
 static inline void
 virtqueue_disable_intr(struct virtqueue *vq)
 {
-       vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+       if (vtpci_packed_queue(vq->hw))
+               virtqueue_disable_intr_packed(vq);
+       else
+               vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+}
+
+/**
+ * Tell the backend to interrupt us.
+ */
+static inline void
+virtqueue_enable_intr_packed(struct virtqueue *vq)
+{
+       uint16_t *off_wrap = &vq->ring_packed.driver_event->desc_event_off_wrap;
+       uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
+
+       *off_wrap = vq->vq_used_cons_idx |
+               ((uint16_t)(vq->used_wrap_counter << 15));
+
+       if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
+               virtio_wmb();
+               vq->event_flags_shadow =
+                       vtpci_with_feature(vq->hw, VIRTIO_RING_F_EVENT_IDX) ?
+                               RING_EVENT_FLAGS_DESC : RING_EVENT_FLAGS_ENABLE;
+               *event_flags = vq->event_flags_shadow;
+       }
 }
+
 /**
  * Tell the backend to interrupt us.
  */
 static inline void
 virtqueue_enable_intr(struct virtqueue *vq)
 {
-       vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
+       if (vtpci_packed_queue(vq->hw))
+               virtqueue_enable_intr_packed(vq);
+       else
+               vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
 }
 /**


IIRC, I asked in previous series to have dedicated functions for split
ring. It does not have any functional change, but it would be clearer
IMHO.

I'm ok that it is done after the series is applied though.

Sorry, I missed this. We'll need another respin anyway so I'll fix it.

regards,
Jens

Reply via email to