From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id BE157918D for ; Thu, 25 May 2017 11:51:18 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga104.jf.intel.com with ESMTP; 25 May 2017 02:51:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,391,1491289200"; d="scan'208";a="91624249" Received: from yliu-dev.sh.intel.com ([10.239.67.162]) by orsmga002.jf.intel.com with ESMTP; 25 May 2017 02:50:57 -0700 From: Yuanhan Liu To: Harish Patil Cc: Yuanhan Liu , dpdk stable Date: Thu, 25 May 2017 17:48:21 +0800 Message-Id: <1495705809-21416-49-git-send-email-yuanhan.liu@linux.intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1495705809-21416-1-git-send-email-yuanhan.liu@linux.intel.com> References: <1495705809-21416-1-git-send-email-yuanhan.liu@linux.intel.com> Subject: [dpdk-stable] patch 'net/qede: prevent crash while changing MTU dynamically' has been queued to stable release 17.02.1 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 May 2017 09:51:19 -0000 Hi, FYI, your patch has been queued to stable release 17.02.1 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 05/28/17. So please shout if anyone has objections. Thanks. --yliu --- >>From 2984313be5e722a71cc96a755cd2d734497cfdc9 Mon Sep 17 00:00:00 2001 From: Harish Patil Date: Fri, 24 Mar 2017 00:40:59 -0700 Subject: [PATCH] net/qede: prevent crash while changing MTU dynamically [ upstream commit 1ef4c3a5c1f76b810620b76d82a31ce33a83d3fe ] The driver can handle dynamic MTU change without needing the port to be stopped explicitly by the application. However, there is currently no check to prevent I/Os from happening on a different thread while the port is going thru' reset internally. This patch fixes this issue by assigning RX/TX burst functions to a dummy function and also reconfigure RX bufsize for each rx queue based on the new MTU value. Fixes: 200645ac7909 ("net/qede: set MTU") Signed-off-by: Harish Patil --- drivers/net/qede/qede_ethdev.c | 57 +++++++++++++++++++++++++++++++----------- drivers/net/qede/qede_rxtx.c | 8 ++++++ drivers/net/qede/qede_rxtx.h | 4 +++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 49ebd9a..039446b 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -1659,32 +1659,61 @@ static int qede_rss_reta_query(struct rte_eth_dev *eth_dev, int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) { - uint32_t frame_size; - struct qede_dev *qdev = dev->data->dev_private; + struct qede_dev *qdev = QEDE_INIT_QDEV(dev); + struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); struct rte_eth_dev_info dev_info = {0}; + struct qede_fastpath *fp; + uint32_t frame_size; + uint16_t rx_buf_size; + uint16_t bufsz; + int i; + PMD_INIT_FUNC_TRACE(edev); qede_dev_info_get(dev, &dev_info); - - /* VLAN_TAG = 4 */ - frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 4; - - if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) + frame_size = mtu + QEDE_ETH_OVERHEAD; + if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) { + DP_ERR(edev, "MTU %u out of range\n", mtu); return -EINVAL; - + } if (!dev->data->scattered_rx && - frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) + frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { + DP_INFO(edev, "MTU greater than minimum RX buffer size of %u\n", + dev->data->min_rx_buf_size); return -EINVAL; - + } + /* Temporarily replace I/O functions with dummy ones. It cannot + * be set to NULL because rte_eth_rx_burst() doesn't check for NULL. + */ + dev->rx_pkt_burst = qede_rxtx_pkts_dummy; + dev->tx_pkt_burst = qede_rxtx_pkts_dummy; + qede_dev_stop(dev); + rte_delay_ms(1000); + qdev->mtu = mtu; + /* Fix up RX buf size for all queues of the port */ + for_each_queue(i) { + fp = &qdev->fp_array[i]; + if (fp->type & QEDE_FASTPATH_RX) { + bufsz = (uint16_t)rte_pktmbuf_data_room_size( + fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; + if (dev->data->scattered_rx) + rx_buf_size = bufsz + QEDE_ETH_OVERHEAD; + else + rx_buf_size = mtu + QEDE_ETH_OVERHEAD; + rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size); + fp->rxq->rx_buf_size = rx_buf_size; + DP_INFO(edev, "buf_size adjusted to %u\n", rx_buf_size); + } + } + qede_dev_start(dev); if (frame_size > ETHER_MAX_LEN) dev->data->dev_conf.rxmode.jumbo_frame = 1; else dev->data->dev_conf.rxmode.jumbo_frame = 0; - /* update max frame size */ dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size; - qdev->mtu = mtu; - qede_dev_stop(dev); - qede_dev_start(dev); + /* Reassign back */ + dev->rx_pkt_burst = qede_recv_pkts; + dev->tx_pkt_burst = qede_xmit_pkts; return 0; } diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c index 329c8e4..7919099 100644 --- a/drivers/net/qede/qede_rxtx.c +++ b/drivers/net/qede/qede_rxtx.c @@ -1582,3 +1582,11 @@ void qede_dev_stop(struct rte_eth_dev *eth_dev) DP_INFO(edev, "dev_state is QEDE_DEV_STOP\n"); } + +uint16_t +qede_rxtx_pkts_dummy(__rte_unused void *p_rxq, + __rte_unused struct rte_mbuf **pkts, + __rte_unused uint16_t nb_pkts) +{ + return 0; +} diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h index 9a393e9..d6cdbc6 100644 --- a/drivers/net/qede/qede_rxtx.h +++ b/drivers/net/qede/qede_rxtx.h @@ -233,6 +233,10 @@ uint16_t qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); +uint16_t qede_rxtx_pkts_dummy(__rte_unused void *p_rxq, + __rte_unused struct rte_mbuf **pkts, + __rte_unused uint16_t nb_pkts); + /* Fastpath resource alloc/dealloc helpers */ int qede_alloc_fp_resc(struct qede_dev *qdev); -- 1.9.0