]> git.droids-corp.org - dpdk.git/commitdiff
net/virtio: flush Rx queues on start
authorTiwei Bie <tiwei.bie@intel.com>
Fri, 20 Oct 2017 02:09:28 +0000 (10:09 +0800)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 24 Oct 2017 19:26:57 +0000 (21:26 +0200)
After starting a device, the driver shouldn't deliver the
packets that already existed before the device is started
to applications. Otherwise it will lead to incorrect packet
collection for port state. This patch fixes this issue by
flushing the Rx queues when starting the device.

Fixes: a85786dc816f ("virtio: fix states handling during initialization")
Cc: stable@dpdk.org
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
Reviewed-by: Jens Freimann <jfreimann@redhat.com>
Acked-by: Yuanhan Liu <yliu@fridaylinux.org>
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_rxtx.c
drivers/net/virtio/virtqueue.c
drivers/net/virtio/virtqueue.h

index 0ec54a9e4db4396b5cf1fe47ad5952f8729ebdf0..bfbd73770c56ac0762b454f64316e05b41b57af2 100644 (file)
@@ -1821,6 +1821,8 @@ virtio_dev_start(struct rte_eth_dev *dev)
 
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
                rxvq = dev->data->rx_queues[i];
+               /* Flush the old packets */
+               virtqueue_flush(rxvq->vq);
                virtqueue_notify(rxvq->vq);
        }
 
index 2cf82fef4ea4957bf2b8484507f0b7c398c40cf3..8560c9c56b4746f2189107bce109bf95354f8677 100644 (file)
@@ -80,7 +80,7 @@ virtio_dev_rx_queue_done(void *rxq, uint16_t offset)
        return VIRTQUEUE_NUSED(vq) >= offset;
 }
 
-static void
+void
 vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
 {
        struct vring_desc *dp, *dp_tail;
index 9ad77b8a3979035090659d05ddbdd6e93b33d87e..c3a536f8a20d77866ecc5568acdc71d38e376a08 100644 (file)
@@ -59,3 +59,28 @@ virtqueue_detatch_unused(struct virtqueue *vq)
                }
        return NULL;
 }
+
+/* Flush the elements in the used ring. */
+void
+virtqueue_flush(struct virtqueue *vq)
+{
+       struct vring_used_elem *uep;
+       struct vq_desc_extra *dxp;
+       uint16_t used_idx, desc_idx;
+       uint16_t nb_used, i;
+
+       nb_used = VIRTQUEUE_NUSED(vq);
+
+       for (i = 0; i < nb_used; i++) {
+               used_idx = vq->vq_used_cons_idx & (vq->vq_nentries - 1);
+               uep = &vq->vq_ring.used->ring[used_idx];
+               desc_idx = (uint16_t)uep->id;
+               dxp = &vq->vq_descx[desc_idx];
+               if (dxp->cookie != NULL) {
+                       rte_pktmbuf_free(dxp->cookie);
+                       dxp->cookie = NULL;
+               }
+               vq->vq_used_cons_idx++;
+               vq_ring_free_chain(vq, desc_idx);
+       }
+}
index 9c4f96d2b44605ec4e3b400bc83aaee0663e06cc..11059fb1fd0b615f4c2d63a86898fa584f0b9e1d 100644 (file)
@@ -304,6 +304,9 @@ void virtqueue_dump(struct virtqueue *vq);
  */
 struct rte_mbuf *virtqueue_detatch_unused(struct virtqueue *vq);
 
+/* Flush the elements in the used ring. */
+void virtqueue_flush(struct virtqueue *vq);
+
 static inline int
 virtqueue_full(const struct virtqueue *vq)
 {
@@ -312,6 +315,8 @@ virtqueue_full(const struct virtqueue *vq)
 
 #define VIRTQUEUE_NUSED(vq) ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
 
+void vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx);
+
 static inline void
 vq_update_avail_idx(struct virtqueue *vq)
 {