[dpdk-dev,v4,26/26] virtio: Fix updating vring descriptor index issue
Commit Message
Updating the vring descriptor index should be done before notifying host;
Remove 2 duplicated store memory barriers in both Rx and Tx path because there is
store memory barrier in vq_update_avail_idx function;
Notify the host only if packets actually transmitted(nb_tx > 0).
Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
---
lib/librte_pmd_virtio/virtio_rxtx.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
@@ -555,15 +555,14 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
}
if (likely(nb_enqueued)) {
- virtio_wmb();
+ vq_update_avail_idx(rxvq);
+
if (unlikely(virtqueue_kick_prepare(rxvq))) {
virtqueue_notify(rxvq);
PMD_RX_LOG(DEBUG, "Notified\n");
}
}
- vq_update_avail_idx(rxvq);
-
return nb_rx;
}
@@ -719,14 +718,14 @@ virtio_recv_mergeable_pkts(void *rx_queue,
}
if (likely(nb_enqueued)) {
+ vq_update_avail_idx(rxvq);
+
if (unlikely(virtqueue_kick_prepare(rxvq))) {
virtqueue_notify(rxvq);
PMD_RX_LOG(DEBUG, "Notified");
}
}
- vq_update_avail_idx(rxvq);
-
return nb_rx;
}
@@ -800,14 +799,16 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
break;
}
}
- vq_update_avail_idx(txvq);
- virtio_wmb();
txvq->packets += nb_tx;
- if (unlikely(virtqueue_kick_prepare(txvq))) {
- virtqueue_notify(txvq);
- PMD_TX_LOG(DEBUG, "Notified backend after xmit");
+ if (likely(nb_tx)) {
+ vq_update_avail_idx(txvq);
+
+ if (unlikely(virtqueue_kick_prepare(txvq))) {
+ virtqueue_notify(txvq);
+ PMD_TX_LOG(DEBUG, "Notified backend after xmit");
+ }
}
return nb_tx;