[dpdk-dev] [PATCH 2/2] net/virtio: support to turn on/off the traffic flow
Zhiyong Yang
zhiyong.yang at intel.com
Fri Mar 31 13:40:19 CEST 2017
virtio_dev_start/stop support the switch of traffic flow.
Signed-off-by: Zhiyong Yang <zhiyong.yang at intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 37 +++++++++++++++++++++++++++-
drivers/net/virtio/virtio_rxtx.c | 12 +++++++++
drivers/net/virtio/virtio_rxtx_simple.c | 4 +++
drivers/net/virtio/virtio_rxtx_simple_neon.c | 5 +++-
drivers/net/virtio/virtio_rxtx_simple_sse.c | 5 +++-
drivers/net/virtio/virtio_user_ethdev.c | 1 +
6 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index d9986ab..5955443 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -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
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index fcd9e93..3ef9678 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -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;
diff --git a/drivers/net/virtio/virtio_rxtx_simple.c b/drivers/net/virtio/virtio_rxtx_simple.c
index b651e53..d061e72 100644
--- a/drivers/net/virtio/virtio_rxtx_simple.c
+++ b/drivers/net/virtio/virtio_rxtx_simple.c
@@ -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();
diff --git a/drivers/net/virtio/virtio_rxtx_simple_neon.c b/drivers/net/virtio/virtio_rxtx_simple_neon.c
index 793eefb..5aa7e2f 100644
--- a/drivers/net/virtio/virtio_rxtx_simple_neon.c
+++ b/drivers/net/virtio/virtio_rxtx_simple_neon.c
@@ -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;
diff --git a/drivers/net/virtio/virtio_rxtx_simple_sse.c b/drivers/net/virtio/virtio_rxtx_simple_sse.c
index 87bb5c6..39fe557 100644
--- a/drivers/net/virtio/virtio_rxtx_simple_sse.c
+++ b/drivers/net/virtio/virtio_rxtx_simple_sse.c
@@ -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;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index d3a5cac..00b35e9 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -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;
--
2.7.4
More information about the dev
mailing list