diff options
author | Damjan Marion <damarion@cisco.com> | 2019-02-02 16:28:16 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-02-02 16:31:07 +0000 |
commit | 1a6ece34358a34367ff1807ac3a9a97b8a120b77 (patch) | |
tree | ff3df0b997689914129c8345e32815bda448298d /build/external/patches/dpdk_18.08 | |
parent | 773291163a4f72f131afc6a84b065bcfed13aeb7 (diff) |
dpdk: bump to dpdk 19.02
HQoS requires fixes to work with dpdk 19.02 so code is disabled and
pending deprecation unless active maintainer is found.
Change-Id: I3569c4287b6dfdd2c29e02375eb53bf01fa6ae84
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'build/external/patches/dpdk_18.08')
7 files changed, 0 insertions, 1190 deletions
diff --git a/build/external/patches/dpdk_18.08/0001-net-mlx5-support-externally-allocated-mempool.patch b/build/external/patches/dpdk_18.08/0001-net-mlx5-support-externally-allocated-mempool.patch deleted file mode 100644 index 87c9cf92469..00000000000 --- a/build/external/patches/dpdk_18.08/0001-net-mlx5-support-externally-allocated-mempool.patch +++ /dev/null @@ -1,270 +0,0 @@ -From bd42c77c457146bede32333558b4e0414b30683e Mon Sep 17 00:00:00 2001 -From: Yongseok Koh <yskoh@mellanox.com> -Date: Fri, 24 Aug 2018 16:46:49 -0700 -Subject: [PATCH] net/mlx5: support externally allocated mempool - -When MLX PMD registers memory for DMA, it accesses the global memseg list -of DPDK to maximize the range of registration so that LKey search can be -more efficient. Granularity of MR registration is per page. - -Externally allocated memory shouldn't be used for DMA because it can't be -searched in the memseg list and free event can't be tracked by DPDK. -However, if the external memory is static (allocated on startup and never -freed), such memory can also be registered by little tweak in the code. - -Signed-off-by: Yongseok Koh <yskoh@mellanox.com> ---- - drivers/net/mlx5/mlx5_mr.c | 155 +++++++++++++++++++++++++++++++++++++++++++ - drivers/net/mlx5/mlx5_rxtx.h | 35 +++++++++- - 2 files changed, 189 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/mlx5/mlx5_mr.c b/drivers/net/mlx5/mlx5_mr.c -index 08105a443..876622e91 100644 ---- a/drivers/net/mlx5/mlx5_mr.c -+++ b/drivers/net/mlx5/mlx5_mr.c -@@ -277,6 +277,23 @@ mr_find_next_chunk(struct mlx5_mr *mr, struct mlx5_mr_cache *entry, - uintptr_t end = 0; - uint32_t idx = 0; - -+ /* MR for external memory doesn't have memseg list. */ -+ if (mr->msl == NULL) { -+ struct ibv_mr *ibv_mr = mr->ibv_mr; -+ -+ assert(mr->ms_bmp_n == 1); -+ assert(mr->ms_n == 1); -+ assert(base_idx == 0); -+ /* -+ * Can't search it from memseg list but get it directly from -+ * verbs MR as there's only one chunk. -+ */ -+ entry->start = (uintptr_t)ibv_mr->addr; -+ entry->end = (uintptr_t)ibv_mr->addr + mr->ibv_mr->length; -+ entry->lkey = rte_cpu_to_be_32(mr->ibv_mr->lkey); -+ /* Returning 1 ends iteration. */ -+ return 1; -+ } - for (idx = base_idx; idx < mr->ms_bmp_n; ++idx) { - if (rte_bitmap_get(mr->ms_bmp, idx)) { - const struct rte_memseg_list *msl; -@@ -818,6 +835,7 @@ mlx5_mr_mem_event_free_cb(struct rte_eth_dev *dev, const void *addr, size_t len) - mr = mr_lookup_dev_list(dev, &entry, start); - if (mr == NULL) - continue; -+ assert(mr->msl); /* Can't be external memory. */ - ms = rte_mem_virt2memseg((void *)start, msl); - assert(ms != NULL); - assert(msl->page_sz == ms->hugepage_sz); -@@ -1070,6 +1088,139 @@ mlx5_mr_flush_local_cache(struct mlx5_mr_ctrl *mr_ctrl) - (void *)mr_ctrl, mr_ctrl->cur_gen); - } - -+/** -+ * Called during rte_mempool_mem_iter() by mlx5_mr_update_ext_mp(). -+ * -+ * Externally allocated chunk is registered and a MR is created for the chunk. -+ * The MR object is added to the global list. If memseg list of a MR object -+ * (mr->msl) is null, the MR object can be regarded as externally allocated -+ * memory. -+ * -+ * Once external memory is registered, it should be static. If the memory is -+ * freed and the virtual address range has different physical memory mapped -+ * again, it may cause crash on device due to the wrong translation entry. PMD -+ * can't track the free event of the external memory for now. -+ */ -+static void -+mlx5_mr_update_ext_mp_cb(struct rte_mempool *mp, void *opaque, -+ struct rte_mempool_memhdr *memhdr, -+ unsigned mem_idx __rte_unused) -+{ -+ struct mr_update_mp_data *data = opaque; -+ struct rte_eth_dev *dev = data->dev; -+ struct priv *priv = dev->data->dev_private; -+ struct mlx5_mr_ctrl *mr_ctrl = data->mr_ctrl; -+ struct mlx5_mr *mr = NULL; -+ uintptr_t addr = (uintptr_t)memhdr->addr; -+ size_t len = memhdr->len; -+ struct mlx5_mr_cache entry; -+ uint32_t lkey; -+ -+ /* If already registered, it should return. */ -+ rte_rwlock_read_lock(&priv->mr.rwlock); -+ lkey = mr_lookup_dev(dev, &entry, addr); -+ rte_rwlock_read_unlock(&priv->mr.rwlock); -+ if (lkey != UINT32_MAX) -+ return; -+ mr = rte_zmalloc_socket(NULL, -+ RTE_ALIGN_CEIL(sizeof(*mr), -+ RTE_CACHE_LINE_SIZE), -+ RTE_CACHE_LINE_SIZE, mp->socket_id); -+ if (mr == NULL) { -+ DRV_LOG(WARNING, -+ "port %u unable to allocate memory for a new MR of" -+ " mempool (%s).", -+ dev->data->port_id, mp->name); -+ data->ret = -1; -+ return; -+ } -+ DRV_LOG(DEBUG, "port %u register MR for chunk #%d of mempool (%s)", -+ dev->data->port_id, mem_idx, mp->name); -+ mr->ibv_mr = mlx5_glue->reg_mr(priv->pd, (void *)addr, len, -+ IBV_ACCESS_LOCAL_WRITE); -+ if (mr->ibv_mr == NULL) { -+ DRV_LOG(WARNING, -+ "port %u fail to create a verbs MR for address (%p)", -+ dev->data->port_id, (void *)addr); -+ rte_free(mr); -+ data->ret = -1; -+ return; -+ } -+ mr->msl = NULL; /* Mark it is external memory. */ -+ mr->ms_bmp = NULL; -+ mr->ms_n = 1; -+ mr->ms_bmp_n = 1; -+ rte_rwlock_write_lock(&priv->mr.rwlock); -+ LIST_INSERT_HEAD(&priv->mr.mr_list, mr, mr); -+ DRV_LOG(DEBUG, -+ "port %u MR CREATED (%p) for external memory %p:\n" -+ " [0x%" PRIxPTR ", 0x%" PRIxPTR ")," -+ " lkey=0x%x base_idx=%u ms_n=%u, ms_bmp_n=%u", -+ dev->data->port_id, (void *)mr, (void *)addr, -+ addr, addr + len, rte_cpu_to_be_32(mr->ibv_mr->lkey), -+ mr->ms_base_idx, mr->ms_n, mr->ms_bmp_n); -+ /* Insert to the global cache table. */ -+ mr_insert_dev_cache(dev, mr); -+ rte_rwlock_write_unlock(&priv->mr.rwlock); -+ /* Insert to the local cache table */ -+ mlx5_mr_addr2mr_bh(dev, mr_ctrl, addr); -+} -+ -+/** -+ * Register MR for entire memory chunks in a Mempool having externally allocated -+ * memory and fill in local cache. -+ * -+ * @param dev -+ * Pointer to Ethernet device. -+ * @param mr_ctrl -+ * Pointer to per-queue MR control structure. -+ * @param mp -+ * Pointer to registering Mempool. -+ * -+ * @return -+ * 0 on success, -1 on failure. -+ */ -+static uint32_t -+mlx5_mr_update_ext_mp(struct rte_eth_dev *dev, struct mlx5_mr_ctrl *mr_ctrl, -+ struct rte_mempool *mp) -+{ -+ struct mr_update_mp_data data = { -+ .dev = dev, -+ .mr_ctrl = mr_ctrl, -+ .ret = 0, -+ }; -+ -+ rte_mempool_mem_iter(mp, mlx5_mr_update_ext_mp_cb, &data); -+ return data.ret; -+} -+ -+/** -+ * Register MR entire memory chunks in a Mempool having externally allocated -+ * memory and search LKey of the address to return. -+ * -+ * @param dev -+ * Pointer to Ethernet device. -+ * @param addr -+ * Search key. -+ * @param mp -+ * Pointer to registering Mempool where addr belongs. -+ * -+ * @return -+ * LKey for address on success, UINT32_MAX on failure. -+ */ -+uint32_t -+mlx5_tx_update_ext_mp(struct mlx5_txq_data *txq, uintptr_t addr, -+ struct rte_mempool *mp) -+{ -+ struct mlx5_txq_ctrl *txq_ctrl = -+ container_of(txq, struct mlx5_txq_ctrl, txq); -+ struct mlx5_mr_ctrl *mr_ctrl = &txq->mr_ctrl; -+ struct priv *priv = txq_ctrl->priv; -+ -+ mlx5_mr_update_ext_mp(ETH_DEV(priv), mr_ctrl, mp); -+ return mlx5_tx_addr2mr_bh(txq, addr); -+} -+ - /* Called during rte_mempool_mem_iter() by mlx5_mr_update_mp(). */ - static void - mlx5_mr_update_mp_cb(struct rte_mempool *mp __rte_unused, void *opaque, -@@ -1113,6 +1264,10 @@ mlx5_mr_update_mp(struct rte_eth_dev *dev, struct mlx5_mr_ctrl *mr_ctrl, - }; - - rte_mempool_mem_iter(mp, mlx5_mr_update_mp_cb, &data); -+ if (data.ret < 0 && rte_errno == ENXIO) { -+ /* Mempool may have externally allocated memory. */ -+ return mlx5_mr_update_ext_mp(dev, mr_ctrl, mp); -+ } - return data.ret; - } - -diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h -index f53bb43c3..b61c23b33 100644 ---- a/drivers/net/mlx5/mlx5_rxtx.h -+++ b/drivers/net/mlx5/mlx5_rxtx.h -@@ -347,6 +347,8 @@ uint16_t mlx5_rx_burst_vec(void *dpdk_txq, struct rte_mbuf **pkts, - void mlx5_mr_flush_local_cache(struct mlx5_mr_ctrl *mr_ctrl); - uint32_t mlx5_rx_addr2mr_bh(struct mlx5_rxq_data *rxq, uintptr_t addr); - uint32_t mlx5_tx_addr2mr_bh(struct mlx5_txq_data *txq, uintptr_t addr); -+uint32_t mlx5_tx_update_ext_mp(struct mlx5_txq_data *txq, uintptr_t addr, -+ struct rte_mempool *mp); - - #ifndef NDEBUG - /** -@@ -534,6 +536,24 @@ mlx5_tx_complete(struct mlx5_txq_data *txq) - } - - /** -+ * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which the -+ * cloned mbuf is allocated is returned instead. -+ * -+ * @param buf -+ * Pointer to mbuf. -+ * -+ * @return -+ * Memory pool where data is located for given mbuf. -+ */ -+static struct rte_mempool * -+mlx5_mb2mp(struct rte_mbuf *buf) -+{ -+ if (unlikely(RTE_MBUF_INDIRECT(buf))) -+ return rte_mbuf_from_indirect(buf)->pool; -+ return buf->pool; -+} -+ -+/** - * Query LKey from a packet buffer for Rx. No need to flush local caches for Rx - * as mempool is pre-configured and static. - * -@@ -591,7 +611,20 @@ mlx5_tx_addr2mr(struct mlx5_txq_data *txq, uintptr_t addr) - return mlx5_tx_addr2mr_bh(txq, addr); - } - --#define mlx5_tx_mb2mr(rxq, mb) mlx5_tx_addr2mr(rxq, (uintptr_t)((mb)->buf_addr)) -+static __rte_always_inline uint32_t -+mlx5_tx_mb2mr(struct mlx5_txq_data *txq, struct rte_mbuf *mb) -+{ -+ uintptr_t addr = (uintptr_t)mb->buf_addr; -+ uint32_t lkey = mlx5_tx_addr2mr(txq, addr); -+ -+ if (likely(lkey != UINT32_MAX)) -+ return lkey; -+ if (rte_errno == ENXIO) { -+ /* Mempool may have externally allocated memory. */ -+ lkey = mlx5_tx_update_ext_mp(txq, addr, mlx5_mb2mp(mb)); -+ } -+ return lkey; -+} - - /** - * Ring TX queue doorbell and flush the update if requested. --- -2.11.0 - diff --git a/build/external/patches/dpdk_18.08/0002-mlx4-support-externally-allocated-mempool.patch b/build/external/patches/dpdk_18.08/0002-mlx4-support-externally-allocated-mempool.patch deleted file mode 100644 index b32862335e5..00000000000 --- a/build/external/patches/dpdk_18.08/0002-mlx4-support-externally-allocated-mempool.patch +++ /dev/null @@ -1,250 +0,0 @@ -From c947fd2ec67e9bbacb8b106f320f6e6bae5a9731 Mon Sep 17 00:00:00 2001 -From: Matthew Smith <mgsmith@netgate.com> -Date: Tue, 28 Aug 2018 13:21:04 -0500 -Subject: [PATCH] mlx4: support externally allocated mempool - -Port Mellanox mlx5 PMD patch to work for mlx4 PMD. - -Signed-off-by: Matthew Smith <mgsmith@netgate.com> ---- - drivers/net/mlx4/mlx4_mr.c | 150 +++++++++++++++++++++++++++++++++++++++++++ - drivers/net/mlx4/mlx4_rxtx.h | 35 +++++++++- - 2 files changed, 184 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/mlx4/mlx4_mr.c b/drivers/net/mlx4/mlx4_mr.c -index d23d3c613..55e5555ce 100644 ---- a/drivers/net/mlx4/mlx4_mr.c -+++ b/drivers/net/mlx4/mlx4_mr.c -@@ -289,6 +289,23 @@ mr_find_next_chunk(struct mlx4_mr *mr, struct mlx4_mr_cache *entry, - uintptr_t end = 0; - uint32_t idx = 0; - -+ /* MR for external memory doesn't have memseg list. */ -+ if (mr->msl == NULL) { -+ struct ibv_mr *ibv_mr = mr->ibv_mr; -+ -+ assert(mr->ms_bmp_n == 1); -+ assert(mr->ms_n == 1); -+ assert(base_idx == 0); -+ /* -+ * Can't search it from memseg list but get it directly from -+ * verbs MR as there's only one chunk. -+ */ -+ entry->start = (uintptr_t)ibv_mr->addr; -+ entry->end = (uintptr_t)ibv_mr->addr + mr->ibv_mr->length; -+ entry->lkey = rte_cpu_to_be_32(mr->ibv_mr->lkey); -+ /* Returning 1 ends iteration. */ -+ return 1; -+ } - for (idx = base_idx; idx < mr->ms_bmp_n; ++idx) { - if (rte_bitmap_get(mr->ms_bmp, idx)) { - const struct rte_memseg_list *msl; -@@ -809,6 +826,7 @@ mlx4_mr_mem_event_free_cb(struct rte_eth_dev *dev, const void *addr, size_t len) - mr = mr_lookup_dev_list(dev, &entry, start); - if (mr == NULL) - continue; -+ assert(mr->msl); /* Can't be external memory. */ - ms = rte_mem_virt2memseg((void *)start, msl); - assert(ms != NULL); - assert(msl->page_sz == ms->hugepage_sz); -@@ -1055,6 +1073,134 @@ mlx4_mr_flush_local_cache(struct mlx4_mr_ctrl *mr_ctrl) - (void *)mr_ctrl, mr_ctrl->cur_gen); - } - -+/** -+ * Called during rte_mempool_mem_iter() by mlx4_mr_update_ext_mp(). -+ * -+ * Externally allocated chunk is registered and a MR is created for the chunk. -+ * The MR object is added to the global list. If memseg list of a MR object -+ * (mr->msl) is null, the MR object can be regarded as externally allocated -+ * memory. -+ * -+ * Once external memory is registered, it should be static. If the memory is -+ * freed and the virtual address range has different physical memory mapped -+ * again, it may cause crash on device due to the wrong translation entry. PMD -+ * can't track the free event of the external memory for now. -+ */ -+static void -+mlx4_mr_update_ext_mp_cb(struct rte_mempool *mp, void *opaque, -+ struct rte_mempool_memhdr *memhdr, -+ unsigned mem_idx __rte_unused) -+{ -+ struct mr_update_mp_data *data = opaque; -+ struct rte_eth_dev *dev = data->dev; -+ struct priv *priv = dev->data->dev_private; -+ struct mlx4_mr_ctrl *mr_ctrl = data->mr_ctrl; -+ struct mlx4_mr *mr = NULL; -+ uintptr_t addr = (uintptr_t)memhdr->addr; -+ size_t len = memhdr->len; -+ struct mlx4_mr_cache entry; -+ uint32_t lkey; -+ -+ /* If already registered, it should return. */ -+ rte_rwlock_read_lock(&priv->mr.rwlock); -+ lkey = mr_lookup_dev(dev, &entry, addr); -+ rte_rwlock_read_unlock(&priv->mr.rwlock); -+ if (lkey != UINT32_MAX) -+ return; -+ mr = rte_zmalloc_socket(NULL, -+ RTE_ALIGN_CEIL(sizeof(*mr), -+ RTE_CACHE_LINE_SIZE), -+ RTE_CACHE_LINE_SIZE, mp->socket_id); -+ if (mr == NULL) { -+ WARN("port %u unable to allocate memory for a new MR of" -+ " mempool (%s).", -+ dev->data->port_id, mp->name); -+ data->ret = -1; -+ return; -+ } -+ DEBUG("port %u register MR for chunk #%d of mempool (%s)", -+ dev->data->port_id, mem_idx, mp->name); -+ mr->ibv_mr = mlx4_glue->reg_mr(priv->pd, (void *)addr, len, -+ IBV_ACCESS_LOCAL_WRITE); -+ if (mr->ibv_mr == NULL) { -+ WARN("port %u fail to create a verbs MR for address (%p)", -+ dev->data->port_id, (void *)addr); -+ rte_free(mr); -+ data->ret = -1; -+ return; -+ } -+ mr->msl = NULL; /* Mark it is external memory. */ -+ mr->ms_bmp = NULL; -+ mr->ms_n = 1; -+ mr->ms_bmp_n = 1; -+ rte_rwlock_write_lock(&priv->mr.rwlock); -+ LIST_INSERT_HEAD(&priv->mr.mr_list, mr, mr); -+ DEBUG("port %u MR CREATED (%p) for external memory %p:\n" -+ " [0x%" PRIxPTR ", 0x%" PRIxPTR ")," -+ " lkey=0x%x base_idx=%u ms_n=%u, ms_bmp_n=%u", -+ dev->data->port_id, (void *)mr, (void *)addr, -+ addr, addr + len, rte_cpu_to_be_32(mr->ibv_mr->lkey), -+ mr->ms_base_idx, mr->ms_n, mr->ms_bmp_n); -+ /* Insert to the global cache table. */ -+ mr_insert_dev_cache(dev, mr); -+ rte_rwlock_write_unlock(&priv->mr.rwlock); -+ /* Insert to the local cache table */ -+ mlx4_mr_addr2mr_bh(dev, mr_ctrl, addr); -+} -+ -+/** -+ * Register MR for entire memory chunks in a Mempool having externally allocated -+ * memory and fill in local cache. -+ * -+ * @param dev -+ * Pointer to Ethernet device. -+ * @param mr_ctrl -+ * Pointer to per-queue MR control structure. -+ * @param mp -+ * Pointer to registering Mempool. -+ * -+ * @return -+ * 0 on success, -1 on failure. -+ */ -+static uint32_t -+mlx4_mr_update_ext_mp(struct rte_eth_dev *dev, struct mlx4_mr_ctrl *mr_ctrl, -+ struct rte_mempool *mp) -+{ -+ struct mr_update_mp_data data = { -+ .dev = dev, -+ .mr_ctrl = mr_ctrl, -+ .ret = 0, -+ }; -+ -+ rte_mempool_mem_iter(mp, mlx4_mr_update_ext_mp_cb, &data); -+ return data.ret; -+} -+ -+/** -+ * Register MR entire memory chunks in a Mempool having externally allocated -+ * memory and search LKey of the address to return. -+ * -+ * @param dev -+ * Pointer to Ethernet device. -+ * @param addr -+ * Search key. -+ * @param mp -+ * Pointer to registering Mempool where addr belongs. -+ * -+ * @return -+ * LKey for address on success, UINT32_MAX on failure. -+ */ -+uint32_t -+mlx4_tx_update_ext_mp(struct txq *txq, uintptr_t addr, -+ struct rte_mempool *mp) -+{ -+ struct mlx4_mr_ctrl *mr_ctrl = &txq->mr_ctrl; -+ struct priv *priv = txq->priv; -+ -+ mlx4_mr_update_ext_mp(priv->dev, mr_ctrl, mp); -+ return mlx4_tx_addr2mr_bh(txq, addr); -+} -+ - /* Called during rte_mempool_mem_iter() by mlx4_mr_update_mp(). */ - static void - mlx4_mr_update_mp_cb(struct rte_mempool *mp __rte_unused, void *opaque, -@@ -1098,6 +1244,10 @@ mlx4_mr_update_mp(struct rte_eth_dev *dev, struct mlx4_mr_ctrl *mr_ctrl, - }; - - rte_mempool_mem_iter(mp, mlx4_mr_update_mp_cb, &data); -+ if (data.ret < 0 && rte_errno == ENXIO) { -+ /* Mempool may have externally allocated memory. */ -+ return mlx4_mr_update_ext_mp(dev, mr_ctrl, mp); -+ } - return data.ret; - } - -diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h -index ffa8abfca..1be060cda 100644 ---- a/drivers/net/mlx4/mlx4_rxtx.h -+++ b/drivers/net/mlx4/mlx4_rxtx.h -@@ -163,6 +163,26 @@ void mlx4_tx_queue_release(void *dpdk_txq); - void mlx4_mr_flush_local_cache(struct mlx4_mr_ctrl *mr_ctrl); - uint32_t mlx4_rx_addr2mr_bh(struct rxq *rxq, uintptr_t addr); - uint32_t mlx4_tx_addr2mr_bh(struct txq *txq, uintptr_t addr); -+uint32_t mlx4_tx_update_ext_mp(struct txq *txq, uintptr_t addr, -+ struct rte_mempool *mp); -+ -+/** -+ * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which the -+ * cloned mbuf is allocated is returned instead. -+ * -+ * @param buf -+ * Pointer to mbuf. -+ * -+ * @return -+ * Memory pool where data is located for given mbuf. -+ */ -+static struct rte_mempool * -+mlx4_mb2mp(struct rte_mbuf *buf) -+{ -+ if (unlikely(RTE_MBUF_INDIRECT(buf))) -+ return rte_mbuf_from_indirect(buf)->pool; -+ return buf->pool; -+} - - /** - * Query LKey from a packet buffer for Rx. No need to flush local caches for Rx -@@ -222,6 +242,19 @@ mlx4_tx_addr2mr(struct txq *txq, uintptr_t addr) - return mlx4_tx_addr2mr_bh(txq, addr); - } - --#define mlx4_tx_mb2mr(rxq, mb) mlx4_tx_addr2mr(rxq, (uintptr_t)((mb)->buf_addr)) -+static __rte_always_inline uint32_t -+mlx4_tx_mb2mr(struct txq *txq, struct rte_mbuf *mb) -+{ -+ uintptr_t addr = (uintptr_t)mb->buf_addr; -+ uint32_t lkey = mlx4_tx_addr2mr(txq, addr); -+ -+ if (likely(lkey != UINT32_MAX)) -+ return lkey; -+ if (rte_errno == ENXIO) { -+ /* Mempool may have externally allocated memory. */ -+ lkey = mlx4_tx_update_ext_mp(txq, addr, mlx4_mb2mp(mb)); -+ } -+ return lkey; -+} - - #endif /* MLX4_RXTX_H_ */ --- -2.15.2 (Apple Git-101.1) - diff --git a/build/external/patches/dpdk_18.08/0003-ixgbe-wait-longer-for-link-after-fiber-MAC-setup.patch b/build/external/patches/dpdk_18.08/0003-ixgbe-wait-longer-for-link-after-fiber-MAC-setup.patch deleted file mode 100644 index 93d1601c677..00000000000 --- a/build/external/patches/dpdk_18.08/0003-ixgbe-wait-longer-for-link-after-fiber-MAC-setup.patch +++ /dev/null @@ -1,39 +0,0 @@ -From ba9b381c532fe57c726752b7db0ab45ab7726c90 Mon Sep 17 00:00:00 2001 -From: Matthew Smith <mgsmith@netgate.com> -Date: Fri, 13 Jul 2018 16:35:57 -0500 -Subject: [PATCH] ixgbe: wait longer for link after fiber MAC setup - -After setting up the link on a fiber port, the maximum wait time for -the link to come up is 500 ms in ixgbe_setup_mac_link_multispeed_fiber(). -On an x550 SFP+ port, this is often not sufficiently long for the link -to come up. This can result in never being able to retrieve accurate -link status for the port using rte_eth_link_get_nowait(). - -Increase the maximum wait time in ixgbe_setup_mac_link_multispeed_fiber() -to 1 s. - -Bugzilla ID: 69 -Fixes: f3430431abaf ("ixgbe/base: add SFP+ dual-speed support") -Cc: stable@dpdk.org - -Signed-off-by: Matthew Smith <mgsmith@netgate.com> ---- - drivers/net/ixgbe/base/ixgbe_common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/ixgbe/base/ixgbe_common.c b/drivers/net/ixgbe/base/ixgbe_common.c -index e7e9256e5..2fb0a072c 100644 ---- a/drivers/net/ixgbe/base/ixgbe_common.c -+++ b/drivers/net/ixgbe/base/ixgbe_common.c -@@ -5296,7 +5296,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, - * Section 73.10.2, we may have to wait up to 500ms if KR is - * attempted. 82599 uses the same timing for 10g SFI. - */ -- for (i = 0; i < 5; i++) { -+ for (i = 0; i < 10; i++) { - /* Wait for the link partner to also set speed */ - msec_delay(100); - --- -2.15.2 (Apple Git-101.1) - diff --git a/build/external/patches/dpdk_18.08/0004-net-i40e-fix-25G-AOC-and-ACC-cable-detection-on-XXV7.patch b/build/external/patches/dpdk_18.08/0004-net-i40e-fix-25G-AOC-and-ACC-cable-detection-on-XXV7.patch deleted file mode 100644 index 14942307d30..00000000000 --- a/build/external/patches/dpdk_18.08/0004-net-i40e-fix-25G-AOC-and-ACC-cable-detection-on-XXV7.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b47596e5d3db40b967b4d67207bb2d87db214f2e Mon Sep 17 00:00:00 2001 -From: Damjan Marion <damarion@cisco.com> -Date: Tue, 25 Sep 2018 10:02:58 +0200 -Subject: [PATCH] net/i40e: fix 25G AOC and ACC cable detection on XXV710 - -Fixes: 75d133dd3296 ("net/i40e: enable 25G device") -Cc: stable@dpdk.org - -Signed-off-by: Damjan Marion <damarion@cisco.com> ---- - drivers/net/i40e/i40e_ethdev.h | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h -index 3fffe5a55..b876933e5 100644 ---- a/drivers/net/i40e/i40e_ethdev.h -+++ b/drivers/net/i40e/i40e_ethdev.h -@@ -1393,6 +1393,8 @@ i40e_calc_itr_interval(bool is_pf, bool is_multi_drv) - (((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_KR) || \ - ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_CR) || \ - ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_SR) || \ -- ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_LR)) -+ ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_LR) || \ -+ ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_AOC) || \ -+ ((phy_type) & I40E_CAP_PHY_TYPE_25GBASE_ACC)) - - #endif /* _I40E_ETHDEV_H_ */ --- -2.17.1 - diff --git a/build/external/patches/dpdk_18.08/0005-mlx5-use-pkg-config-SUSE-libmnl.patch b/build/external/patches/dpdk_18.08/0005-mlx5-use-pkg-config-SUSE-libmnl.patch deleted file mode 100644 index 454a85e83d1..00000000000 --- a/build/external/patches/dpdk_18.08/0005-mlx5-use-pkg-config-SUSE-libmnl.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c030dc71ff4069c5b5e5b7889a2926617075f6e3 Mon Sep 17 00:00:00 2001 -From: Stephen Hemminger <stephen@networkplumber.org> -Date: Thu, 25 Oct 2018 10:33:01 -0700 -Subject: [PATCH] mlx5: use pkg-config to handle SUSE libmnl - -SUSE decided to install the libmnl include file in a non-standard -place: /usr/include/libmnl/libmnl/libmnl.h - -This was probably a mistake by the SUSE package maintainer, -but hard to get fixed. Workaround the problem by pkg-config to find -the necessary include directive for libmnl. - -Fixes: 20b71e92ef8e ("net/mlx5: lay groundwork for switch offloads") -Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> ---- - drivers/net/mlx5/Makefile | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile -index 1e9c0b42ac16..8497c98ef86e 100644 ---- a/drivers/net/mlx5/Makefile -+++ b/drivers/net/mlx5/Makefile -@@ -51,6 +51,7 @@ CFLAGS += -D_DEFAULT_SOURCE - CFLAGS += -D_XOPEN_SOURCE=600 - CFLAGS += $(WERROR_FLAGS) - CFLAGS += -Wno-strict-prototypes -+CFLAGS += $(shell pkg-config --cflags libmnl) - ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y) - CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"' - CFLAGS += -DMLX5_GLUE_VERSION='"$(LIB_GLUE_VERSION)"' -@@ -57,7 +58,7 @@ LDLIBS += -ldl - else - LDLIBS += -libverbs -lmlx5 - endif --LDLIBS += -lmnl -+LDLIBS += $(shell pkg-config --libs libmnl) - LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring - LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs - LDLIBS += -lrte_bus_pci diff --git a/build/external/patches/dpdk_18.08/0005-net-ena-recreate-HW-IO-rings-on-start-and-stop.patch b/build/external/patches/dpdk_18.08/0005-net-ena-recreate-HW-IO-rings-on-start-and-stop.patch deleted file mode 100644 index 4e45b2139d5..00000000000 --- a/build/external/patches/dpdk_18.08/0005-net-ena-recreate-HW-IO-rings-on-start-and-stop.patch +++ /dev/null @@ -1,359 +0,0 @@ -From 792dd52ca1a513fc16ee56b789c7e3177cb782f7 Mon Sep 17 00:00:00 2001 -From: Michal Krawczyk <mk@semihalf.com> -Date: Wed, 24 Oct 2018 11:37:17 +0200 -Subject: [PATCH] net/ena: recreate HW IO rings on start and stop - -On the start the driver was refilling all Rx buffs, but the old ones -were not released. That way running start/stop for a few times was -causing device to run out of descriptors. - -To fix the issue, IO rings are now being destroyed on stop, and -recreated on start. That is way the device is not losing any -descriptors. - -Furthermore, there was also memory leak for the Rx mbufs, which were -created on start and not destroyed on stop. - -Change-Id: I01dfd036d0bff517e42e35257481de4983679763 ---- - drivers/net/ena/ena_ethdev.c | 196 ++++++++++++++++++++----------------------- - 1 file changed, 91 insertions(+), 105 deletions(-) - -diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c -index c255dc6..de5d2ed 100644 ---- a/drivers/net/ena/ena_ethdev.c -+++ b/drivers/net/ena/ena_ethdev.c -@@ -239,6 +239,8 @@ static void ena_rx_queue_release_bufs(struct ena_ring *ring); - static void ena_tx_queue_release_bufs(struct ena_ring *ring); - static int ena_link_update(struct rte_eth_dev *dev, - int wait_to_complete); -+static int ena_create_io_queue(struct ena_ring *ring); -+static void ena_free_io_queues_all(struct ena_adapter *adapter); - static int ena_queue_restart(struct ena_ring *ring); - static int ena_queue_restart_all(struct rte_eth_dev *dev, - enum ena_ring_type ring_type); -@@ -510,7 +512,8 @@ static void ena_close(struct rte_eth_dev *dev) - struct ena_adapter *adapter = - (struct ena_adapter *)(dev->data->dev_private); - -- ena_stop(dev); -+ if (adapter->state == ENA_ADAPTER_STATE_RUNNING) -+ ena_stop(dev); - adapter->state = ENA_ADAPTER_STATE_CLOSED; - - ena_rx_queue_release_all(dev); -@@ -746,21 +749,12 @@ static void ena_tx_queue_release_all(struct rte_eth_dev *dev) - static void ena_rx_queue_release(void *queue) - { - struct ena_ring *ring = (struct ena_ring *)queue; -- struct ena_adapter *adapter = ring->adapter; -- int ena_qid; - - ena_assert_msg(ring->configured, - "API violation - releasing not configured queue"); - ena_assert_msg(ring->adapter->state != ENA_ADAPTER_STATE_RUNNING, - "API violation"); - -- /* Destroy HW queue */ -- ena_qid = ENA_IO_RXQ_IDX(ring->id); -- ena_com_destroy_io_queue(&adapter->ena_dev, ena_qid); -- -- /* Free all bufs */ -- ena_rx_queue_release_bufs(ring); -- - /* Free ring resources */ - if (ring->rx_buffer_info) - rte_free(ring->rx_buffer_info); -@@ -779,18 +773,12 @@ static void ena_rx_queue_release(void *queue) - static void ena_tx_queue_release(void *queue) - { - struct ena_ring *ring = (struct ena_ring *)queue; -- struct ena_adapter *adapter = ring->adapter; -- int ena_qid; - - ena_assert_msg(ring->configured, - "API violation. Releasing not configured queue"); - ena_assert_msg(ring->adapter->state != ENA_ADAPTER_STATE_RUNNING, - "API violation"); - -- /* Destroy HW queue */ -- ena_qid = ENA_IO_TXQ_IDX(ring->id); -- ena_com_destroy_io_queue(&adapter->ena_dev, ena_qid); -- - /* Free all bufs */ - ena_tx_queue_release_bufs(ring); - -@@ -1078,10 +1066,86 @@ static void ena_stop(struct rte_eth_dev *dev) - (struct ena_adapter *)(dev->data->dev_private); - - rte_timer_stop_sync(&adapter->timer_wd); -+ ena_free_io_queues_all(adapter); - - adapter->state = ENA_ADAPTER_STATE_STOPPED; - } - -+static int ena_create_io_queue(struct ena_ring *ring) -+{ -+ struct ena_adapter *adapter; -+ struct ena_com_dev *ena_dev; -+ struct ena_com_create_io_ctx ctx = -+ /* policy set to _HOST just to satisfy icc compiler */ -+ { ENA_ADMIN_PLACEMENT_POLICY_HOST, -+ 0, 0, 0, 0, 0 }; -+ uint16_t ena_qid; -+ int rc; -+ -+ adapter = ring->adapter; -+ ena_dev = &adapter->ena_dev; -+ -+ if (ring->type == ENA_RING_TYPE_TX) { -+ ena_qid = ENA_IO_TXQ_IDX(ring->id); -+ ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX; -+ ctx.mem_queue_type = ena_dev->tx_mem_queue_type; -+ ctx.queue_size = adapter->tx_ring_size; -+ } else { -+ ena_qid = ENA_IO_RXQ_IDX(ring->id); -+ ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX; -+ ctx.queue_size = adapter->rx_ring_size; -+ } -+ ctx.qid = ena_qid; -+ ctx.msix_vector = -1; /* interrupts not used */ -+ ctx.numa_node = ena_cpu_to_node(ring->id); -+ -+ rc = ena_com_create_io_queue(ena_dev, &ctx); -+ if (rc) { -+ RTE_LOG(ERR, PMD, -+ "failed to create io queue #%d (qid:%d) rc: %d\n", -+ ring->id, ena_qid, rc); -+ return rc; -+ } -+ -+ rc = ena_com_get_io_handlers(ena_dev, ena_qid, -+ &ring->ena_com_io_sq, -+ &ring->ena_com_io_cq); -+ if (rc) { -+ RTE_LOG(ERR, PMD, -+ "Failed to get io queue handlers. queue num %d rc: %d\n", -+ ring->id, rc); -+ ena_com_destroy_io_queue(ena_dev, ena_qid); -+ return rc; -+ } -+ -+ if (ring->type == ENA_RING_TYPE_TX) -+ ena_com_update_numa_node(ring->ena_com_io_cq, ctx.numa_node); -+ -+ return 0; -+} -+ -+static void ena_free_io_queues_all(struct ena_adapter *adapter) -+{ -+ struct rte_eth_dev *eth_dev = adapter->rte_dev; -+ struct ena_com_dev *ena_dev = &adapter->ena_dev; -+ int i; -+ uint16_t ena_qid; -+ uint16_t nb_rxq = eth_dev->data->nb_rx_queues; -+ uint16_t nb_txq = eth_dev->data->nb_tx_queues; -+ -+ for (i = 0; i < nb_txq; ++i) { -+ ena_qid = ENA_IO_TXQ_IDX(i); -+ ena_com_destroy_io_queue(ena_dev, ena_qid); -+ } -+ -+ for (i = 0; i < nb_rxq; ++i) { -+ ena_qid = ENA_IO_RXQ_IDX(i); -+ ena_com_destroy_io_queue(ena_dev, ena_qid); -+ -+ ena_rx_queue_release_bufs(&adapter->rx_ring[i]); -+ } -+} -+ - static int ena_queue_restart(struct ena_ring *ring) - { - int rc, bufs_num; -@@ -1089,6 +1153,12 @@ static int ena_queue_restart(struct ena_ring *ring) - ena_assert_msg(ring->configured == 1, - "Trying to restart unconfigured queue\n"); - -+ rc = ena_create_io_queue(ring); -+ if (rc) { -+ PMD_INIT_LOG(ERR, "Failed to create IO queue!\n"); -+ return rc; -+ } -+ - ring->next_to_clean = 0; - ring->next_to_use = 0; - -@@ -1111,17 +1181,10 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev, - __rte_unused unsigned int socket_id, - const struct rte_eth_txconf *tx_conf) - { -- struct ena_com_create_io_ctx ctx = -- /* policy set to _HOST just to satisfy icc compiler */ -- { ENA_ADMIN_PLACEMENT_POLICY_HOST, -- ENA_COM_IO_QUEUE_DIRECTION_TX, 0, 0, 0, 0 }; - struct ena_ring *txq = NULL; - struct ena_adapter *adapter = - (struct ena_adapter *)(dev->data->dev_private); - unsigned int i; -- int ena_qid; -- int rc; -- struct ena_com_dev *ena_dev = &adapter->ena_dev; - - txq = &adapter->tx_ring[queue_idx]; - -@@ -1146,37 +1209,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev, - return -EINVAL; - } - -- ena_qid = ENA_IO_TXQ_IDX(queue_idx); -- -- ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX; -- ctx.qid = ena_qid; -- ctx.msix_vector = -1; /* admin interrupts not used */ -- ctx.mem_queue_type = ena_dev->tx_mem_queue_type; -- ctx.queue_size = adapter->tx_ring_size; -- ctx.numa_node = ena_cpu_to_node(queue_idx); -- -- rc = ena_com_create_io_queue(ena_dev, &ctx); -- if (rc) { -- RTE_LOG(ERR, PMD, -- "failed to create io TX queue #%d (qid:%d) rc: %d\n", -- queue_idx, ena_qid, rc); -- return rc; -- } -- txq->ena_com_io_cq = &ena_dev->io_cq_queues[ena_qid]; -- txq->ena_com_io_sq = &ena_dev->io_sq_queues[ena_qid]; -- -- rc = ena_com_get_io_handlers(ena_dev, ena_qid, -- &txq->ena_com_io_sq, -- &txq->ena_com_io_cq); -- if (rc) { -- RTE_LOG(ERR, PMD, -- "Failed to get TX queue handlers. TX queue num %d rc: %d\n", -- queue_idx, rc); -- goto err_destroy_io_queue; -- } -- -- ena_com_update_numa_node(txq->ena_com_io_cq, ctx.numa_node); -- - txq->port_id = dev->data->port_id; - txq->next_to_clean = 0; - txq->next_to_use = 0; -@@ -1188,8 +1220,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev, - RTE_CACHE_LINE_SIZE); - if (!txq->tx_buffer_info) { - RTE_LOG(ERR, PMD, "failed to alloc mem for tx buffer info\n"); -- rc = -ENOMEM; -- goto err_destroy_io_queue; -+ return -ENOMEM; - } - - txq->empty_tx_reqs = rte_zmalloc("txq->empty_tx_reqs", -@@ -1197,8 +1228,8 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev, - RTE_CACHE_LINE_SIZE); - if (!txq->empty_tx_reqs) { - RTE_LOG(ERR, PMD, "failed to alloc mem for tx reqs\n"); -- rc = -ENOMEM; -- goto err_free; -+ rte_free(txq->tx_buffer_info); -+ return -ENOMEM; - } - - for (i = 0; i < txq->ring_size; i++) -@@ -1214,13 +1245,6 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev, - dev->data->tx_queues[queue_idx] = txq; - - return 0; -- --err_free: -- rte_free(txq->tx_buffer_info); -- --err_destroy_io_queue: -- ena_com_destroy_io_queue(ena_dev, ena_qid); -- return rc; - } - - static int ena_rx_queue_setup(struct rte_eth_dev *dev, -@@ -1230,16 +1254,10 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev, - __rte_unused const struct rte_eth_rxconf *rx_conf, - struct rte_mempool *mp) - { -- struct ena_com_create_io_ctx ctx = -- /* policy set to _HOST just to satisfy icc compiler */ -- { ENA_ADMIN_PLACEMENT_POLICY_HOST, -- ENA_COM_IO_QUEUE_DIRECTION_RX, 0, 0, 0, 0 }; - struct ena_adapter *adapter = - (struct ena_adapter *)(dev->data->dev_private); - struct ena_ring *rxq = NULL; -- uint16_t ena_qid = 0; -- int i, rc = 0; -- struct ena_com_dev *ena_dev = &adapter->ena_dev; -+ int i; - - rxq = &adapter->rx_ring[queue_idx]; - if (rxq->configured) { -@@ -1263,36 +1281,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev, - return -EINVAL; - } - -- ena_qid = ENA_IO_RXQ_IDX(queue_idx); -- -- ctx.qid = ena_qid; -- ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX; -- ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; -- ctx.msix_vector = -1; /* admin interrupts not used */ -- ctx.queue_size = adapter->rx_ring_size; -- ctx.numa_node = ena_cpu_to_node(queue_idx); -- -- rc = ena_com_create_io_queue(ena_dev, &ctx); -- if (rc) { -- RTE_LOG(ERR, PMD, "failed to create io RX queue #%d rc: %d\n", -- queue_idx, rc); -- return rc; -- } -- -- rxq->ena_com_io_cq = &ena_dev->io_cq_queues[ena_qid]; -- rxq->ena_com_io_sq = &ena_dev->io_sq_queues[ena_qid]; -- -- rc = ena_com_get_io_handlers(ena_dev, ena_qid, -- &rxq->ena_com_io_sq, -- &rxq->ena_com_io_cq); -- if (rc) { -- RTE_LOG(ERR, PMD, -- "Failed to get RX queue handlers. RX queue num %d rc: %d\n", -- queue_idx, rc); -- ena_com_destroy_io_queue(ena_dev, ena_qid); -- return rc; -- } -- - rxq->port_id = dev->data->port_id; - rxq->next_to_clean = 0; - rxq->next_to_use = 0; -@@ -1304,7 +1292,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev, - RTE_CACHE_LINE_SIZE); - if (!rxq->rx_buffer_info) { - RTE_LOG(ERR, PMD, "failed to alloc mem for rx buffer info\n"); -- ena_com_destroy_io_queue(ena_dev, ena_qid); - return -ENOMEM; - } - -@@ -1315,7 +1302,6 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev, - RTE_LOG(ERR, PMD, "failed to alloc mem for empty rx reqs\n"); - rte_free(rxq->rx_buffer_info); - rxq->rx_buffer_info = NULL; -- ena_com_destroy_io_queue(ena_dev, ena_qid); - return -ENOMEM; - } - -@@ -1326,7 +1312,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev, - rxq->configured = 1; - dev->data->rx_queues[queue_idx] = rxq; - -- return rc; -+ return 0; - } - - static int ena_populate_rx_queue(struct ena_ring *rxq, unsigned int count) --- -2.7.4 - diff --git a/build/external/patches/dpdk_18.08/0006-net-bonding-fix-buffer-corruption-in-packets.patch b/build/external/patches/dpdk_18.08/0006-net-bonding-fix-buffer-corruption-in-packets.patch deleted file mode 100644 index 3a13a7dff00..00000000000 --- a/build/external/patches/dpdk_18.08/0006-net-bonding-fix-buffer-corruption-in-packets.patch +++ /dev/null @@ -1,203 +0,0 @@ -commit 6b2a47d -Author: Jia Yu <jyu@vmware.com> -AuthorDate: Sun Aug 19 22:18:45 2018 -0700 -Commit: Ferruh Yigit <ferruh.yigit@intel.com> -CommitDate: Tue Aug 28 15:27:39 2018 +0200 - - net/bonding: fix buffer corruption in packets - - When bond slave devices cannot transmit all packets in bufs array, - tx_burst callback shall merge the un-transmitted packets back to - bufs array. Recent merge logic introduced a bug which causes - invalid mbuf addresses being written to bufs array. - When caller frees the un-transmitted packets, due to invalid addresses, - application will crash. - - The fix is avoid shifting mbufs, and directly write un-transmitted - packets back to bufs array. - - Fixes: 09150784a776 ("net/bonding: burst mode hash calculation") - Cc: stable@dpdk.org - - Signed-off-by: Jia Yu <jyu@vmware.com> - Acked-by: Chas Williams <chas3@att.com> - -diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c -index 4417422..b84f322 100644 ---- a/drivers/net/bonding/rte_eth_bond_pmd.c -+++ b/drivers/net/bonding/rte_eth_bond_pmd.c -@@ -301,10 +301,10 @@ bond_ethdev_tx_burst_8023ad_fast_queue(void *queue, struct rte_mbuf **bufs, - /* Mapping array generated by hash function to map mbufs to slaves */ - uint16_t bufs_slave_port_idxs[RTE_MAX_ETHPORTS] = { 0 }; - -- uint16_t slave_tx_count, slave_tx_fail_count[RTE_MAX_ETHPORTS] = { 0 }; -+ uint16_t slave_tx_count; - uint16_t total_tx_count = 0, total_tx_fail_count = 0; - -- uint16_t i, j; -+ uint16_t i; - - if (unlikely(nb_bufs == 0)) - return 0; -@@ -359,34 +359,12 @@ bond_ethdev_tx_burst_8023ad_fast_queue(void *queue, struct rte_mbuf **bufs, - - /* If tx burst fails move packets to end of bufs */ - if (unlikely(slave_tx_count < slave_nb_bufs[i])) { -- slave_tx_fail_count[i] = slave_nb_bufs[i] - -+ int slave_tx_fail_count = slave_nb_bufs[i] - - slave_tx_count; -- total_tx_fail_count += slave_tx_fail_count[i]; -- -- /* -- * Shift bufs to beginning of array to allow reordering -- * later -- */ -- for (j = 0; j < slave_tx_fail_count[i]; j++) { -- slave_bufs[i][j] = -- slave_bufs[i][(slave_tx_count - 1) + j]; -- } -- } -- } -- -- /* -- * If there are tx burst failures we move packets to end of bufs to -- * preserve expected PMD behaviour of all failed transmitted being -- * at the end of the input mbuf array -- */ -- if (unlikely(total_tx_fail_count > 0)) { -- int bufs_idx = nb_bufs - total_tx_fail_count - 1; -- -- for (i = 0; i < slave_count; i++) { -- if (slave_tx_fail_count[i] > 0) { -- for (j = 0; j < slave_tx_fail_count[i]; j++) -- bufs[bufs_idx++] = slave_bufs[i][j]; -- } -+ total_tx_fail_count += slave_tx_fail_count; -+ memcpy(&bufs[nb_bufs - total_tx_fail_count], -+ &slave_bufs[i][slave_tx_count], -+ slave_tx_fail_count * sizeof(bufs[0])); - } - } - -@@ -716,8 +694,8 @@ bond_ethdev_tx_burst_round_robin(void *queue, struct rte_mbuf **bufs, - tx_fail_total += tx_fail_slave; - - memcpy(&bufs[nb_pkts - tx_fail_total], -- &slave_bufs[i][num_tx_slave], -- tx_fail_slave * sizeof(bufs[0])); -+ &slave_bufs[i][num_tx_slave], -+ tx_fail_slave * sizeof(bufs[0])); - } - num_tx_total += num_tx_slave; - } -@@ -1222,10 +1200,10 @@ bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs, - /* Mapping array generated by hash function to map mbufs to slaves */ - uint16_t bufs_slave_port_idxs[nb_bufs]; - -- uint16_t slave_tx_count, slave_tx_fail_count[RTE_MAX_ETHPORTS] = { 0 }; -+ uint16_t slave_tx_count; - uint16_t total_tx_count = 0, total_tx_fail_count = 0; - -- uint16_t i, j; -+ uint16_t i; - - if (unlikely(nb_bufs == 0)) - return 0; -@@ -1266,34 +1244,12 @@ bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs, - - /* If tx burst fails move packets to end of bufs */ - if (unlikely(slave_tx_count < slave_nb_bufs[i])) { -- slave_tx_fail_count[i] = slave_nb_bufs[i] - -+ int slave_tx_fail_count = slave_nb_bufs[i] - - slave_tx_count; -- total_tx_fail_count += slave_tx_fail_count[i]; -- -- /* -- * Shift bufs to beginning of array to allow reordering -- * later -- */ -- for (j = 0; j < slave_tx_fail_count[i]; j++) { -- slave_bufs[i][j] = -- slave_bufs[i][(slave_tx_count - 1) + j]; -- } -- } -- } -- -- /* -- * If there are tx burst failures we move packets to end of bufs to -- * preserve expected PMD behaviour of all failed transmitted being -- * at the end of the input mbuf array -- */ -- if (unlikely(total_tx_fail_count > 0)) { -- int bufs_idx = nb_bufs - total_tx_fail_count - 1; -- -- for (i = 0; i < slave_count; i++) { -- if (slave_tx_fail_count[i] > 0) { -- for (j = 0; j < slave_tx_fail_count[i]; j++) -- bufs[bufs_idx++] = slave_bufs[i][j]; -- } -+ total_tx_fail_count += slave_tx_fail_count; -+ memcpy(&bufs[nb_bufs - total_tx_fail_count], -+ &slave_bufs[i][slave_tx_count], -+ slave_tx_fail_count * sizeof(bufs[0])); - } - } - -@@ -1320,10 +1276,10 @@ bond_ethdev_tx_burst_8023ad(void *queue, struct rte_mbuf **bufs, - /* Mapping array generated by hash function to map mbufs to slaves */ - uint16_t bufs_slave_port_idxs[RTE_MAX_ETHPORTS] = { 0 }; - -- uint16_t slave_tx_count, slave_tx_fail_count[RTE_MAX_ETHPORTS] = { 0 }; -+ uint16_t slave_tx_count; - uint16_t total_tx_count = 0, total_tx_fail_count = 0; - -- uint16_t i, j; -+ uint16_t i; - - if (unlikely(nb_bufs == 0)) - return 0; -@@ -1381,39 +1337,13 @@ bond_ethdev_tx_burst_8023ad(void *queue, struct rte_mbuf **bufs, - - /* If tx burst fails move packets to end of bufs */ - if (unlikely(slave_tx_count < slave_nb_bufs[i])) { -- slave_tx_fail_count[i] = slave_nb_bufs[i] - -+ int slave_tx_fail_count = slave_nb_bufs[i] - - slave_tx_count; -- total_tx_fail_count += slave_tx_fail_count[i]; -- -- /* -- * Shift bufs to beginning of array to allow -- * reordering later -- */ -- for (j = 0; j < slave_tx_fail_count[i]; j++) -- slave_bufs[i][j] = -- slave_bufs[i] -- [(slave_tx_count - 1) -- + j]; -- } -- } -+ total_tx_fail_count += slave_tx_fail_count; - -- /* -- * If there are tx burst failures we move packets to end of -- * bufs to preserve expected PMD behaviour of all failed -- * transmitted being at the end of the input mbuf array -- */ -- if (unlikely(total_tx_fail_count > 0)) { -- int bufs_idx = nb_bufs - total_tx_fail_count - 1; -- -- for (i = 0; i < slave_count; i++) { -- if (slave_tx_fail_count[i] > 0) { -- for (j = 0; -- j < slave_tx_fail_count[i]; -- j++) { -- bufs[bufs_idx++] = -- slave_bufs[i][j]; -- } -- } -+ memcpy(&bufs[nb_bufs - total_tx_fail_count], -+ &slave_bufs[i][slave_tx_count], -+ slave_tx_fail_count * sizeof(bufs[0])); - } - } - } |