2018-01-29 13:11:30 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright 2017 6WIND S.A.
|
2018-03-20 19:20:35 +00:00
|
|
|
* Copyright 2017 Mellanox Technologies, Ltd
|
2017-07-06 18:41:10 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
/* Verbs header. */
|
|
|
|
/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
|
|
|
|
#ifdef PEDANTIC
|
|
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
|
|
#endif
|
|
|
|
#include <infiniband/verbs.h>
|
2017-09-26 15:38:24 +00:00
|
|
|
#include <infiniband/mlx5dv.h>
|
2017-07-06 18:41:10 +00:00
|
|
|
#ifdef PEDANTIC
|
|
|
|
#pragma GCC diagnostic error "-Wpedantic"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <rte_mbuf.h>
|
|
|
|
#include <rte_mempool.h>
|
|
|
|
#include <rte_prefetch.h>
|
|
|
|
|
|
|
|
#include "mlx5.h"
|
|
|
|
#include "mlx5_utils.h"
|
|
|
|
#include "mlx5_rxtx.h"
|
2017-10-09 18:46:56 +00:00
|
|
|
#include "mlx5_rxtx_vec.h"
|
2017-07-06 18:41:10 +00:00
|
|
|
#include "mlx5_autoconf.h"
|
|
|
|
#include "mlx5_defs.h"
|
|
|
|
#include "mlx5_prm.h"
|
|
|
|
|
2017-10-09 18:47:00 +00:00
|
|
|
#if defined RTE_ARCH_X86_64
|
2017-10-09 18:46:57 +00:00
|
|
|
#include "mlx5_rxtx_vec_sse.h"
|
2017-10-09 18:47:00 +00:00
|
|
|
#elif defined RTE_ARCH_ARM64
|
|
|
|
#include "mlx5_rxtx_vec_neon.h"
|
2017-10-09 18:46:57 +00:00
|
|
|
#else
|
|
|
|
#error "This should not be compiled if SIMD instructions are not supported."
|
2017-07-06 18:41:10 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Skip error packets.
|
|
|
|
*
|
|
|
|
* @param rxq
|
|
|
|
* Pointer to RX queue structure.
|
|
|
|
* @param[out] pkts
|
|
|
|
* Array to store received packets.
|
|
|
|
* @param pkts_n
|
|
|
|
* Maximum number of packets in array.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* Number of packets successfully received (<= pkts_n).
|
|
|
|
*/
|
|
|
|
static uint16_t
|
2017-10-09 14:44:39 +00:00
|
|
|
rxq_handle_pending_error(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts,
|
2017-07-06 18:41:10 +00:00
|
|
|
uint16_t pkts_n)
|
|
|
|
{
|
|
|
|
uint16_t n = 0;
|
|
|
|
unsigned int i;
|
2017-08-02 17:25:54 +00:00
|
|
|
#ifdef MLX5_PMD_SOFT_COUNTERS
|
|
|
|
uint32_t err_bytes = 0;
|
|
|
|
#endif
|
2017-07-06 18:41:10 +00:00
|
|
|
|
|
|
|
for (i = 0; i < pkts_n; ++i) {
|
|
|
|
struct rte_mbuf *pkt = pkts[i];
|
|
|
|
|
net/mlx5: extend Rx completion with error handling
When WQEs are posted to the HW to receive packets, the PMD may receive
a completion report with error from the HW, aka error CQE which is
associated to a bad WQE.
The error reason may be bad address, wrong lkey, small buffer size,
etc. that can wrongly be configured by the PMD or by the user.
Checking all the optional mistakes to prevent error CQEs doesn't make
sense due to performance impacts, moreover, some error CQEs can be
triggered because of the packets coming from the wire when the DPDK
application has no any control.
Most of the error CQE types change the RQ state to error state what
causes all the next received packets to be dropped by the HW and to be
completed with CQE flush error forever.
The current solution detects these error CQEs and even reports the
errors to the user by the statistics error counters but without
recovery, so if the RQ inserted to the error state it never moves to
ready state again and all the next packets ever will be dropped.
Extend the error CQEs handling for recovery by moving the state to
ready again, and rearranging all the RQ WQEs and the management
variables appropriately.
Sometimes the error CQE root cause is very hard to debug and even may
be related to some corner cases which are not reproducible easily,
hence a dump file with debug information will be created for the first
number of error CQEs, this number can be configured by the PMD probe
parameters.
Cc: stable@dpdk.org
Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Shahaf Shuler <shahafs@mellanox.com>
2019-05-30 10:20:36 +00:00
|
|
|
if (pkt->packet_type == RTE_PTYPE_ALL_MASK || rxq->err_state) {
|
2017-08-02 17:25:54 +00:00
|
|
|
#ifdef MLX5_PMD_SOFT_COUNTERS
|
|
|
|
err_bytes += PKT_LEN(pkt);
|
|
|
|
#endif
|
2017-07-06 18:41:10 +00:00
|
|
|
rte_pktmbuf_free_seg(pkt);
|
2017-08-02 17:25:54 +00:00
|
|
|
} else {
|
2017-07-06 18:41:10 +00:00
|
|
|
pkts[n++] = pkt;
|
2017-08-02 17:25:54 +00:00
|
|
|
}
|
2017-07-06 18:41:10 +00:00
|
|
|
}
|
|
|
|
rxq->stats.idropped += (pkts_n - n);
|
2017-08-02 17:25:54 +00:00
|
|
|
#ifdef MLX5_PMD_SOFT_COUNTERS
|
|
|
|
/* Correct counters of errored completions. */
|
|
|
|
rxq->stats.ipackets -= (pkts_n - n);
|
|
|
|
rxq->stats.ibytes -= err_bytes;
|
|
|
|
#endif
|
net/mlx5: extend Rx completion with error handling
When WQEs are posted to the HW to receive packets, the PMD may receive
a completion report with error from the HW, aka error CQE which is
associated to a bad WQE.
The error reason may be bad address, wrong lkey, small buffer size,
etc. that can wrongly be configured by the PMD or by the user.
Checking all the optional mistakes to prevent error CQEs doesn't make
sense due to performance impacts, moreover, some error CQEs can be
triggered because of the packets coming from the wire when the DPDK
application has no any control.
Most of the error CQE types change the RQ state to error state what
causes all the next received packets to be dropped by the HW and to be
completed with CQE flush error forever.
The current solution detects these error CQEs and even reports the
errors to the user by the statistics error counters but without
recovery, so if the RQ inserted to the error state it never moves to
ready state again and all the next packets ever will be dropped.
Extend the error CQEs handling for recovery by moving the state to
ready again, and rearranging all the RQ WQEs and the management
variables appropriately.
Sometimes the error CQE root cause is very hard to debug and even may
be related to some corner cases which are not reproducible easily,
hence a dump file with debug information will be created for the first
number of error CQEs, this number can be configured by the PMD probe
parameters.
Cc: stable@dpdk.org
Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Shahaf Shuler <shahafs@mellanox.com>
2019-05-30 10:20:36 +00:00
|
|
|
mlx5_rx_err_handle(rxq, 1);
|
2017-07-06 18:41:10 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* DPDK callback for vectorized RX.
|
|
|
|
*
|
|
|
|
* @param dpdk_rxq
|
|
|
|
* Generic pointer to RX queue structure.
|
|
|
|
* @param[out] pkts
|
|
|
|
* Array to store received packets.
|
|
|
|
* @param pkts_n
|
|
|
|
* Maximum number of packets in array.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* Number of packets successfully received (<= pkts_n).
|
|
|
|
*/
|
|
|
|
uint16_t
|
|
|
|
mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
|
|
|
|
{
|
2017-10-09 14:44:39 +00:00
|
|
|
struct mlx5_rxq_data *rxq = dpdk_rxq;
|
2017-07-06 18:41:10 +00:00
|
|
|
uint16_t nb_rx;
|
2018-01-09 17:38:50 +00:00
|
|
|
uint64_t err = 0;
|
2017-07-06 18:41:10 +00:00
|
|
|
|
2018-01-09 17:38:50 +00:00
|
|
|
nb_rx = rxq_burst_v(rxq, pkts, pkts_n, &err);
|
net/mlx5: extend Rx completion with error handling
When WQEs are posted to the HW to receive packets, the PMD may receive
a completion report with error from the HW, aka error CQE which is
associated to a bad WQE.
The error reason may be bad address, wrong lkey, small buffer size,
etc. that can wrongly be configured by the PMD or by the user.
Checking all the optional mistakes to prevent error CQEs doesn't make
sense due to performance impacts, moreover, some error CQEs can be
triggered because of the packets coming from the wire when the DPDK
application has no any control.
Most of the error CQE types change the RQ state to error state what
causes all the next received packets to be dropped by the HW and to be
completed with CQE flush error forever.
The current solution detects these error CQEs and even reports the
errors to the user by the statistics error counters but without
recovery, so if the RQ inserted to the error state it never moves to
ready state again and all the next packets ever will be dropped.
Extend the error CQEs handling for recovery by moving the state to
ready again, and rearranging all the RQ WQEs and the management
variables appropriately.
Sometimes the error CQE root cause is very hard to debug and even may
be related to some corner cases which are not reproducible easily,
hence a dump file with debug information will be created for the first
number of error CQEs, this number can be configured by the PMD probe
parameters.
Cc: stable@dpdk.org
Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Shahaf Shuler <shahafs@mellanox.com>
2019-05-30 10:20:36 +00:00
|
|
|
if (unlikely(err | rxq->err_state))
|
2017-07-06 18:41:10 +00:00
|
|
|
nb_rx = rxq_handle_pending_error(rxq, pkts, nb_rx);
|
|
|
|
return nb_rx;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check a RX queue can support vectorized RX.
|
|
|
|
*
|
|
|
|
* @param rxq
|
|
|
|
* Pointer to RX queue.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* 1 if supported, negative errno value if not.
|
|
|
|
*/
|
|
|
|
int __attribute__((cold))
|
2018-03-05 12:21:04 +00:00
|
|
|
mlx5_rxq_check_vec_support(struct mlx5_rxq_data *rxq)
|
2017-07-06 18:41:10 +00:00
|
|
|
{
|
2017-10-09 14:44:39 +00:00
|
|
|
struct mlx5_rxq_ctrl *ctrl =
|
|
|
|
container_of(rxq, struct mlx5_rxq_ctrl, rxq);
|
2017-08-02 15:32:56 +00:00
|
|
|
|
2018-05-09 11:13:50 +00:00
|
|
|
if (mlx5_mprq_enabled(ETH_DEV(ctrl->priv)))
|
|
|
|
return -ENOTSUP;
|
2018-01-10 09:16:58 +00:00
|
|
|
if (!ctrl->priv->config.rx_vec_en || rxq->sges_n != 0)
|
2017-07-06 18:41:10 +00:00
|
|
|
return -ENOTSUP;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check a device can support vectorized RX.
|
|
|
|
*
|
2018-03-05 12:21:04 +00:00
|
|
|
* @param dev
|
|
|
|
* Pointer to Ethernet device.
|
2017-07-06 18:41:10 +00:00
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* 1 if supported, negative errno value if not.
|
|
|
|
*/
|
|
|
|
int __attribute__((cold))
|
2018-03-05 12:21:04 +00:00
|
|
|
mlx5_check_vec_rx_support(struct rte_eth_dev *dev)
|
2017-07-06 18:41:10 +00:00
|
|
|
{
|
2019-02-21 09:29:14 +00:00
|
|
|
struct mlx5_priv *priv = dev->data->dev_private;
|
2017-07-06 18:41:10 +00:00
|
|
|
uint16_t i;
|
|
|
|
|
2018-01-10 09:16:58 +00:00
|
|
|
if (!priv->config.rx_vec_en)
|
2017-08-02 15:32:56 +00:00
|
|
|
return -ENOTSUP;
|
2018-05-09 11:13:50 +00:00
|
|
|
if (mlx5_mprq_enabled(dev))
|
|
|
|
return -ENOTSUP;
|
2019-07-29 11:53:25 +00:00
|
|
|
if (mlx5_lro_on(dev))
|
|
|
|
return -ENOTSUP;
|
2017-07-06 18:41:10 +00:00
|
|
|
/* All the configured queues should support. */
|
|
|
|
for (i = 0; i < priv->rxqs_n; ++i) {
|
2017-10-09 14:44:39 +00:00
|
|
|
struct mlx5_rxq_data *rxq = (*priv->rxqs)[i];
|
2017-07-06 18:41:10 +00:00
|
|
|
|
2017-10-09 14:44:44 +00:00
|
|
|
if (!rxq)
|
|
|
|
continue;
|
2018-03-05 12:21:04 +00:00
|
|
|
if (mlx5_rxq_check_vec_support(rxq) < 0)
|
2017-07-06 18:41:10 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i != priv->rxqs_n)
|
|
|
|
return -ENOTSUP;
|
|
|
|
return 1;
|
|
|
|
}
|