diff options
author | Daniele Di Proietto <diproiettod@vmware.com> | 2016-11-15 15:40:49 -0800 |
---|---|---|
committer | Daniele Di Proietto <diproiettod@vmware.com> | 2017-01-15 19:25:11 -0800 |
commit | 3b1fb0779b87788968c1a6a9ff295a9883547485 (patch) | |
tree | 1340e16aaf8e3be35fa01047dd5c1318782771bf | |
parent | 57eebbb4c3151cdf4c56419c1fea15cfdf0acba4 (diff) | |
download | openvswitch-3b1fb0779b87788968c1a6a9ff295a9883547485.tar.gz |
netdev-dpdk: Don't call rte_dev_stop() in update_flags().
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 <diproiettod@vmware.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
-rw-r--r-- | lib/netdev-dpdk.c | 28 |
1 files changed, 12 insertions, 16 deletions
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 409ee6405..659d136fc 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) { @@ -1598,6 +1597,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); @@ -1828,6 +1831,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); @@ -2292,8 +2300,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; } @@ -2307,20 +2313,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 |