Calling rte_eth_dev_stop() while the device is running causes a crash. We could use rte_eth_dev_set_link_down(), but not every PMD implements that, and I found one NIC where that has no effect.
Instead, this commit checks if the device has the NETDEV_UP flag when transmitting or receiving (similarly to what we do for vhostuser). I didn't notice any performance difference with this check in case the device is up. An alternative would be to remove the device queues from the pmd threads tx and receive cache, but that requires reconfiguration and I'd prefer to avoid it, because the change can come from OpenFlow. Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com> --- lib/netdev-dpdk.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 8bb908691..2df3e220c 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -783,8 +783,6 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) mbp_priv = rte_mempool_get_priv(dev->dpdk_mp->mp); dev->buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM; - dev->flags = NETDEV_UP | NETDEV_PROMISC; - /* Get the Flow control configuration for DPDK-ETH */ diag = rte_eth_dev_flow_ctrl_get(dev->port_id, &dev->fc_conf); if (diag) { @@ -890,6 +888,9 @@ netdev_dpdk_init(struct netdev *netdev, unsigned int port_no, /* Initilize the hardware offload flags to 0 */ dev->hw_ol_features = 0; + + dev->flags = NETDEV_UP | NETDEV_PROMISC; + if (type == DPDK_DEV_ETH) { if (rte_eth_dev_is_valid_port(dev->port_id)) { err = dpdk_eth_dev_init(dev); @@ -900,8 +901,6 @@ netdev_dpdk_init(struct netdev *netdev, unsigned int port_no, dev->tx_q = netdev_dpdk_alloc_txq(netdev->n_txq); } else { dev->tx_q = netdev_dpdk_alloc_txq(OVS_VHOST_MAX_QUEUE_NUM); - /* Enable DPDK_DEV_VHOST device and set promiscuous mode flag. */ - dev->flags = NETDEV_UP | NETDEV_PROMISC; } if (!dev->tx_q) { @@ -1591,6 +1590,10 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch) int nb_rx; int dropped = 0; + if (OVS_UNLIKELY(!(dev->flags & NETDEV_UP))) { + return EAGAIN; + } + nb_rx = rte_eth_rx_burst(rx->port_id, rxq->queue_id, (struct rte_mbuf **) batch->packets, NETDEV_MAX_BURST); @@ -1821,6 +1824,11 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, struct dp_packet_batch *batch, bool may_steal, bool concurrent_txq) { + if (OVS_UNLIKELY(!(dev->flags & NETDEV_UP))) { + dp_packet_delete_batch(batch, may_steal); + return; + } + if (OVS_UNLIKELY(concurrent_txq)) { qid = qid % dev->up.n_txq; rte_spinlock_lock(&dev->tx_q[qid].tx_lock); @@ -2285,8 +2293,6 @@ netdev_dpdk_update_flags__(struct netdev_dpdk *dev, enum netdev_flags *old_flagsp) OVS_REQUIRES(dev->mutex) { - int err; - if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) { return EINVAL; } @@ -2300,20 +2306,10 @@ netdev_dpdk_update_flags__(struct netdev_dpdk *dev, } if (dev->type == DPDK_DEV_ETH) { - if (dev->flags & NETDEV_UP) { - err = rte_eth_dev_start(dev->port_id); - if (err) - return -err; - } - if (dev->flags & NETDEV_PROMISC) { rte_eth_promiscuous_enable(dev->port_id); } - if (!(dev->flags & NETDEV_UP)) { - rte_eth_dev_stop(dev->port_id); - } - netdev_change_seq_changed(&dev->up); } else { /* If DPDK_DEV_VHOST device's NETDEV_UP flag was changed and vhost is -- 2.11.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev