@@ -1707,6 +1707,33 @@ virtio_dev_configure(struct rte_eth_dev *dev)
return 0;
}
+static void
+update_queuing_status(struct rte_eth_dev *dev)
+{
+ struct virtio_hw *hw = dev->data->dev_private;
+ unsigned int i;
+ struct virtnet_rx *vnet_rx;
+ struct virtnet_tx *vnet_tx;
+ int allow_queuing = 1;
+
+ if (rte_atomic32_read(&hw->started) == 0)
+ allow_queuing = 0;
+
+ /* Wait until rx/tx_pkt_burst stops accessing virtio device */
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ vnet_rx = dev->data->rx_queues[i];
+ if (!vnet_rx)
+ continue;
+ rte_atomic32_set(&vnet_rx->allow_queuing, allow_queuing);
+ }
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ vnet_tx = dev->data->tx_queues[i];
+ if (!vnet_tx)
+ continue;
+ rte_atomic32_set(&vnet_tx->allow_queuing, allow_queuing);
+ }
+}
static int
virtio_dev_start(struct rte_eth_dev *dev)
@@ -1758,6 +1785,9 @@ virtio_dev_start(struct rte_eth_dev *dev)
virtqueue_notify(rxvq->vq);
}
+ rte_atomic32_set(&hw->started, 1);
+ update_queuing_status(dev);
+
PMD_INIT_LOG(DEBUG, "Notified backend at initialization");
for (i = 0; i < dev->data->nb_rx_queues; i++) {
@@ -1819,13 +1849,15 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
}
/*
- * Stop device: disable interrupt and mark link down
+ * Stop device: disable interrupt, mark link down
+ * and stop the traffic flow.
*/
static void
virtio_dev_stop(struct rte_eth_dev *dev)
{
struct rte_eth_link link;
struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
+ struct virtio_hw *hw = dev->data->dev_private;
PMD_INIT_LOG(DEBUG, "stop");
@@ -1834,6 +1866,9 @@ virtio_dev_stop(struct rte_eth_dev *dev)
memset(&link, 0, sizeof(link));
virtio_dev_atomic_write_link_status(dev, &link);
+
+ rte_atomic32_set(&hw->started, 0);
+ update_queuing_status(dev);
}
static int
@@ -736,6 +736,10 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
int offload;
struct virtio_net_hdr *hdr;
+ nb_rx = 0;
+ if (unlikely(rte_atomic32_read(&rxvq->allow_queuing) == 0))
+ return nb_rx;
+
nb_used = VIRTQUEUE_NUSED(vq);
virtio_rmb();
@@ -850,6 +854,10 @@ virtio_recv_mergeable_pkts(void *rx_queue,
uint32_t hdr_size;
int offload;
+ nb_rx = 0;
+ if (unlikely(rte_atomic32_read(&rxvq->allow_queuing) == 0))
+ return nb_rx;
+
nb_used = VIRTQUEUE_NUSED(vq);
virtio_rmb();
@@ -1012,6 +1020,10 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
uint16_t nb_used, nb_tx;
int error;
+ nb_tx = 0;
+ if (unlikely(rte_atomic32_read(&txvq->allow_queuing) == 0))
+ return nb_tx;
+
if (unlikely(nb_pkts < 1))
return nb_pkts;
@@ -95,6 +95,10 @@ virtio_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_tail, nb_commit;
int i;
uint16_t desc_idx_max = (vq->vq_nentries >> 1) - 1;
+ uint16_t nb_tx = 0;
+
+ if (unlikely(rte_atomic32_read(&txvq->allow_queuing) == 0))
+ return nb_tx;
nb_used = VIRTQUEUE_NUSED(vq);
rte_compiler_barrier();
@@ -77,7 +77,7 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
struct vring_used_elem *rused;
struct rte_mbuf **sw_ring;
struct rte_mbuf **sw_ring_end;
- uint16_t nb_pkts_received;
+ uint16_t nb_pkts_received = 0;
uint8x16_t shuf_msk1 = {
0xFF, 0xFF, 0xFF, 0xFF, /* packet type */
@@ -106,6 +106,9 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
0, 0
};
+ if (unlikely(rte_atomic32_read(&rxvq->allow_queuing) == 0))
+ return nb_pkts_received;
+
if (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP))
return 0;
@@ -79,7 +79,7 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
struct vring_used_elem *rused;
struct rte_mbuf **sw_ring;
struct rte_mbuf **sw_ring_end;
- uint16_t nb_pkts_received;
+ uint16_t nb_pkts_received = 0;
__m128i shuf_msk1, shuf_msk2, len_adjust;
shuf_msk1 = _mm_set_epi8(
@@ -109,6 +109,9 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
0, (uint16_t)-vq->hw->vtnet_hdr_size,
0, 0);
+ if (unlikely(rte_atomic32_read(&rxvq->allow_queuing) == 0))
+ return nb_pkts_received;
+
if (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP))
return 0;
@@ -318,6 +318,7 @@ virtio_user_eth_dev_alloc(const char *name)
hw->modern = 0;
hw->use_simple_rxtx = 0;
hw->virtio_user_dev = dev;
+ rte_atomic32_set(&hw->started, 0);
data->dev_private = hw;
data->drv_name = virtio_user_driver.driver.name;
data->numa_node = SOCKET_ID_ANY;