From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f46.google.com (mail-wm0-f46.google.com [74.125.82.46]) by dpdk.org (Postfix) with ESMTP id 37E1B995F for ; Tue, 1 Aug 2017 09:56:18 +0200 (CEST) Received: by mail-wm0-f46.google.com with SMTP id k20so20876632wmg.0 for ; Tue, 01 Aug 2017 00:56:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=4CSmfXZTJj7dp6apxatzSW6aPHz23l+i17Ljw1SCMPA=; b=GR7w5Thkam9bhzxbRoX4DgNzHFsxSxKLWgmw6sYZOD7pqxRKNhz41x7QGPzZ7XiLj5 wgVzlMWaBRAT420YyEYfpk8TEbAfILZa1ADib+c/37r3841HwzUkFsH/HXAba3p+ts1U X+ZY4b3apm7sFhOk1MHFYzOQeXE43avKJF+VAH15LXsQd7ZwqfcGtNllGJmPdM7sUMgD c2Fa/4KjY+BG7GY0xfAuWTmkKqktRr8KVKPQFkd7ic2URlkTRXz9aEB66vyZgD5smT0p 0H4CBPuI17AsJNnuruqVHb6c3tC3IJp4hexDbT7L7esT8+iSJ+WbYJzVWMUxUwWKCrgR OnCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=4CSmfXZTJj7dp6apxatzSW6aPHz23l+i17Ljw1SCMPA=; b=T6mJjurCCuxAdKNLAU0ZZgMj2v49PgWXjjn5MZ+YRNLSDl1WLzRai/I5y7uzz0+aNi RiU9eSfwSW3V4eIct34pitvJzl3i5tqEWQGkFBmiGNJIcxcg0ICG5hlw/OWsWzO90VsF aApJJ72qelbLQC0ilRImdC1QxDzNrkY0Xp7he9h8Iy4GOE2hRn0LL5z8UD/HbgnZoh/j 1kxFE8A8MWAb0yt/AzC8C0oe/pIpmeUStDaPU3mivhvmoq0vOP/pufgQcfmEdr3WfluI V4+D+Fkf+D82FR5ktMPLHa5OKJbSzvp2CnOYpsfxe1ZY4D2Wqi2sgOhsAp9D99PzUokt 5fzQ== X-Gm-Message-State: AIVw1127aoGWpl/lPX49+K5DtUqhY32CC7McICgX0jtRr9s7VrXyQh7/ 9ol5bgWgAlGv5DhV X-Received: by 10.28.151.199 with SMTP id z190mr771061wmd.100.1501574177639; Tue, 01 Aug 2017 00:56:17 -0700 (PDT) Received: from ping.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id l8sm707045wmd.15.2017.08.01.00.56.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 01 Aug 2017 00:56:17 -0700 (PDT) From: Nelio Laranjeiro To: dev@dpdk.org Cc: Yongseok Koh , stable@dpdk.org Date: Tue, 1 Aug 2017 09:55:57 +0200 Message-Id: <1501574157-1676-1-git-send-email-nelio.laranjeiro@6wind.com> X-Mailer: git-send-email 2.1.4 Subject: [dpdk-stable] [PATCH] net/mlx5: fix MTU update 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: Tue, 01 Aug 2017 07:56:18 -0000 Changing the MTU is not related to changing the number of segments, activating or not the multi-segment support should be handled by the application. Fixes: 9964b965ad69 ("net/mlx5: re-add Rx scatter support") Cc: stable@dpdk.org Signed-off-by: Nelio Laranjeiro Acked-by: Yongseok Koh --- drivers/net/mlx5/mlx5_ethdev.c | 127 ++++++----------------------------------- drivers/net/mlx5/mlx5_rxq.c | 67 ---------------------- drivers/net/mlx5/mlx5_rxtx.h | 1 - 3 files changed, 16 insertions(+), 179 deletions(-) diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 08cc814..b0eb3cd 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -924,12 +924,6 @@ mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) /** * DPDK callback to change the MTU. * - * Setting the MTU affects hardware MRU (packets larger than the MTU cannot be - * received). Use this as a hint to enable/disable scattered packets support - * and improve performance when not needed. - * Since failure is not an option, reconfiguring queues on the fly is not - * recommended. - * * @param dev * Pointer to Ethernet device structure. * @param in_mtu @@ -942,122 +936,33 @@ int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) { struct priv *priv = dev->data->dev_private; + uint16_t kern_mtu; int ret = 0; - unsigned int i; - unsigned int max_frame_len; - int rehash; - int restart = priv->started; if (mlx5_is_secondary()) return -E_RTE_SECONDARY; priv_lock(priv); + ret = priv_get_mtu(priv, &kern_mtu); + if (ret) + goto out; /* Set kernel interface MTU first. */ - if (priv_set_mtu(priv, mtu)) { - ret = errno; - WARN("cannot set port %u MTU to %u: %s", priv->port, mtu, - strerror(ret)); + ret = priv_set_mtu(priv, mtu); + if (ret) goto out; - } else + ret = priv_get_mtu(priv, &kern_mtu); + if (ret) + goto out; + if (kern_mtu == mtu) { + priv->mtu = mtu; DEBUG("adapter port %u MTU set to %u", priv->port, mtu); - /* Temporarily replace RX handler with a fake one, assuming it has not - * been copied elsewhere. */ - dev->rx_pkt_burst = removed_rx_burst; - /* Make sure everyone has left dev->rx_pkt_burst() and uses - * removed_rx_burst() instead. */ - rte_wmb(); - usleep(1000); - /* MTU does not include header and CRC. */ - max_frame_len = ETHER_HDR_LEN + mtu + ETHER_CRC_LEN; - /* Check if at least one queue is going to need a SGE update. */ - for (i = 0; i != priv->rxqs_n; ++i) { - struct rxq *rxq = (*priv->rxqs)[i]; - unsigned int mb_len; - unsigned int size = RTE_PKTMBUF_HEADROOM + max_frame_len; - unsigned int sges_n; - - if (rxq == NULL) - continue; - mb_len = rte_pktmbuf_data_room_size(rxq->mp); - assert(mb_len >= RTE_PKTMBUF_HEADROOM); - /* - * Determine the number of SGEs needed for a full packet - * and round it to the next power of two. - */ - sges_n = log2above((size / mb_len) + !!(size % mb_len)); - if (sges_n != rxq->sges_n) - break; } - /* - * If all queues have the right number of SGEs, a simple rehash - * of their buffers is enough, otherwise SGE information can only - * be updated in a queue by recreating it. All resources that depend - * on queues (flows, indirection tables) must be recreated as well in - * that case. - */ - rehash = (i == priv->rxqs_n); - if (!rehash) { - /* Clean up everything as with mlx5_dev_stop(). */ - priv_special_flow_disable_all(priv); - priv_mac_addrs_disable(priv); - priv_destroy_hash_rxqs(priv); - priv_fdir_disable(priv); - priv_dev_interrupt_handler_uninstall(priv, dev); - } -recover: - /* Reconfigure each RX queue. */ - for (i = 0; (i != priv->rxqs_n); ++i) { - struct rxq *rxq = (*priv->rxqs)[i]; - struct rxq_ctrl *rxq_ctrl = - container_of(rxq, struct rxq_ctrl, rxq); - unsigned int mb_len; - unsigned int tmp; - - if (rxq == NULL) - continue; - mb_len = rte_pktmbuf_data_room_size(rxq->mp); - assert(mb_len >= RTE_PKTMBUF_HEADROOM); - /* Provide new values to rxq_setup(). */ - dev->data->dev_conf.rxmode.jumbo_frame = - (max_frame_len > ETHER_MAX_LEN); - dev->data->dev_conf.rxmode.max_rx_pkt_len = max_frame_len; - if (rehash) - ret = rxq_rehash(dev, rxq_ctrl); - else - ret = rxq_ctrl_setup(dev, rxq_ctrl, 1 << rxq->elts_n, - rxq_ctrl->socket, NULL, rxq->mp); - if (!ret) - continue; - /* Attempt to roll back in case of error. */ - tmp = (mb_len << rxq->sges_n) - RTE_PKTMBUF_HEADROOM; - if (max_frame_len != tmp) { - max_frame_len = tmp; - goto recover; - } - /* Double fault, disable RX. */ - break; - } - /* Mimic mlx5_dev_start(). */ - if (ret) { - ERROR("unable to reconfigure RX queues, RX disabled"); - } else if (restart && - !rehash && - !priv_create_hash_rxqs(priv) && - !priv_rehash_flows(priv)) { - if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_NONE) - priv_fdir_enable(priv); - priv_dev_interrupt_handler_install(priv, dev); - } - priv->mtu = mtu; - /* Burst functions can now be called again. */ - rte_wmb(); - /* - * Use a safe RX burst function in case of error, otherwise select RX - * burst function again. - */ - if (!ret) - priv_select_rx_function(priv); + priv_unlock(priv); + return 0; out: + ret = errno; + WARN("cannot set port %u MTU to %u: %s", priv->port, mtu, + strerror(ret)); priv_unlock(priv); assert(ret >= 0); return -ret; diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c index 34ec95b..118a2d9 100644 --- a/drivers/net/mlx5/mlx5_rxq.c +++ b/drivers/net/mlx5/mlx5_rxq.c @@ -797,73 +797,6 @@ rxq_cleanup(struct rxq_ctrl *rxq_ctrl) } /** - * Reconfigure RX queue buffers. - * - * rxq_rehash() does not allocate mbufs, which, if not done from the right - * thread (such as a control thread), may corrupt the pool. - * In case of failure, the queue is left untouched. - * - * @param dev - * Pointer to Ethernet device structure. - * @param rxq_ctrl - * RX queue pointer. - * - * @return - * 0 on success, errno value on failure. - */ -int -rxq_rehash(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl) -{ - unsigned int elts_n = 1 << rxq_ctrl->rxq.elts_n; - unsigned int i; - struct ibv_exp_wq_attr mod; - int err; - - DEBUG("%p: rehashing queue %p with %u SGE(s) per packet", - (void *)dev, (void *)rxq_ctrl, 1 << rxq_ctrl->rxq.sges_n); - assert(!(elts_n % (1 << rxq_ctrl->rxq.sges_n))); - /* From now on, any failure will render the queue unusable. - * Reinitialize WQ. */ - mod = (struct ibv_exp_wq_attr){ - .attr_mask = IBV_EXP_WQ_ATTR_STATE, - .wq_state = IBV_EXP_WQS_RESET, - }; - err = ibv_exp_modify_wq(rxq_ctrl->wq, &mod); - if (err) { - ERROR("%p: cannot reset WQ: %s", (void *)dev, strerror(err)); - assert(err > 0); - return err; - } - /* Snatch mbufs from original queue. */ - claim_zero(rxq_trim_elts(&rxq_ctrl->rxq)); - claim_zero(rxq_alloc_elts(rxq_ctrl, elts_n, rxq_ctrl->rxq.elts)); - for (i = 0; i != elts_n; ++i) { - struct rte_mbuf *buf = (*rxq_ctrl->rxq.elts)[i]; - - assert(rte_mbuf_refcnt_read(buf) == 2); - rte_pktmbuf_free_seg(buf); - } - /* Change queue state to ready. */ - mod = (struct ibv_exp_wq_attr){ - .attr_mask = IBV_EXP_WQ_ATTR_STATE, - .wq_state = IBV_EXP_WQS_RDY, - }; - err = ibv_exp_modify_wq(rxq_ctrl->wq, &mod); - if (err) { - ERROR("%p: WQ state to IBV_EXP_WQS_RDY failed: %s", - (void *)dev, strerror(err)); - goto error; - } - /* Update doorbell counter. */ - rxq_ctrl->rxq.rq_ci = elts_n >> rxq_ctrl->rxq.sges_n; - rte_wmb(); - *rxq_ctrl->rxq.rq_db = htonl(rxq_ctrl->rxq.rq_ci); -error: - assert(err >= 0); - return err; -} - -/** * Initialize RX queue. * * @param tmpl diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h index 02184ae..eda8b00 100644 --- a/drivers/net/mlx5/mlx5_rxtx.h +++ b/drivers/net/mlx5/mlx5_rxtx.h @@ -307,7 +307,6 @@ void priv_destroy_hash_rxqs(struct priv *); int priv_allow_flow_type(struct priv *, enum hash_rxq_flow_type); int priv_rehash_flows(struct priv *); void rxq_cleanup(struct rxq_ctrl *); -int rxq_rehash(struct rte_eth_dev *, struct rxq_ctrl *); int rxq_ctrl_setup(struct rte_eth_dev *, struct rxq_ctrl *, uint16_t, unsigned int, const struct rte_eth_rxconf *, struct rte_mempool *); -- 2.1.4