summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Di Proietto <diproiettod@vmware.com>2016-11-15 15:40:49 -0800
committerDaniele Di Proietto <diproiettod@vmware.com>2017-01-15 19:25:11 -0800
commit3b1fb0779b87788968c1a6a9ff295a9883547485 (patch)
tree1340e16aaf8e3be35fa01047dd5c1318782771bf
parent57eebbb4c3151cdf4c56419c1fea15cfdf0acba4 (diff)
downloadopenvswitch-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.c28
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