Hi,
> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Friday, January 27, 2023 5:22 AM
> To: dev@dpdk.org
> Cc: stable@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>; Matan
> Azrad <matan@nvidia.com>; Slava Ovsiienko <viacheslavo@nvidia.com>
> Subject: [PATCH] net/mlx5: fix error CQE dumping for vectorized Rx burst
>
> There is a dump file with debug information created
> for an error CQE to help with troubleshooting later.
> It starts with the last CQE, which, presumably is the error CQE.
> But this is only true for the scalar Rx burst routing since
> we handle CQEs there one by one and detect the error immediately.
> For vectorized Rx bursts, we may already move to another CQE
> when we detect the error since we handle CQEs in batches there.
> Go back to the error CQE in this case to dump proper CQE.
>
> Fixes: 88c0733535 ("net/mlx5: extend Rx completion with error handling")
> Cc: stable@dpdk.org
>
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
Patch applied to next-net-mlx,
Kindest regards,
Raslan Darawsheh
@@ -425,12 +425,14 @@ mlx5_rxq_initialize(struct mlx5_rxq_data *rxq)
* @param[in] vec
* 1 when called from vectorized Rx burst, need to prepare mbufs for the RQ.
* 0 when called from non-vectorized Rx burst.
+ * @param[in] err_n
+ * Number of CQEs to check for an error.
*
* @return
* MLX5_RECOVERY_ERROR_RET in case of recovery error, otherwise the CQE status.
*/
int
-mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec)
+mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec, uint16_t err_n)
{
const uint16_t cqe_n = 1 << rxq->cqe_n;
const uint16_t cqe_mask = cqe_n - 1;
@@ -442,13 +444,18 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec)
volatile struct mlx5_cqe *cqe;
volatile struct mlx5_err_cqe *err_cqe;
} u = {
- .cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_mask],
+ .cqe = &(*rxq->cqes)[(rxq->cq_ci - vec) & cqe_mask],
};
struct mlx5_mp_arg_queue_state_modify sm;
- int ret;
+ int ret, i;
switch (rxq->err_state) {
case MLX5_RXQ_ERR_STATE_NO_ERROR:
+ for (i = 0; i < (int)err_n; i++) {
+ u.cqe = &(*rxq->cqes)[(rxq->cq_ci - vec - i) & cqe_mask];
+ if (MLX5_CQE_OPCODE(u.cqe->op_own) == MLX5_CQE_RESP_ERR)
+ break;
+ }
rxq->err_state = MLX5_RXQ_ERR_STATE_NEED_RESET;
/* Fall-through */
case MLX5_RXQ_ERR_STATE_NEED_RESET:
@@ -507,7 +514,6 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec)
rxq->elts_ci : rxq->rq_ci;
uint32_t elt_idx;
struct rte_mbuf **elt;
- int i;
unsigned int n = elts_n - (elts_ci -
rxq->rq_pi);
@@ -628,7 +634,7 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe,
if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) {
if (unlikely(ret == MLX5_CQE_STATUS_ERR ||
rxq->err_state)) {
- ret = mlx5_rx_err_handle(rxq, 0);
+ ret = mlx5_rx_err_handle(rxq, 0, 1);
if (ret == MLX5_CQE_STATUS_HW_OWN ||
ret == MLX5_RECOVERY_ERROR_RET)
return MLX5_ERROR_CQE_RET;
@@ -286,7 +286,8 @@ int mlx5_hrxq_modify(struct rte_eth_dev *dev, uint32_t hxrq_idx,
uint16_t mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n);
void mlx5_rxq_initialize(struct mlx5_rxq_data *rxq);
-__rte_noinline int mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec);
+__rte_noinline int mlx5_rx_err_handle(struct mlx5_rxq_data *rxq,
+ uint8_t vec, uint16_t err_n);
void mlx5_mprq_buf_free(struct mlx5_mprq_buf *buf);
uint16_t mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts,
uint16_t pkts_n);
@@ -74,7 +74,7 @@ rxq_handle_pending_error(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts,
rxq->stats.ipackets -= (pkts_n - n);
rxq->stats.ibytes -= err_bytes;
#endif
- mlx5_rx_err_handle(rxq, 1);
+ mlx5_rx_err_handle(rxq, 1, pkts_n);
return n;
}
@@ -253,8 +253,6 @@ rxq_copy_mprq_mbuf_v(struct mlx5_rxq_data *rxq,
}
rxq->rq_pi += i;
rxq->cq_ci += i;
- rte_io_wmb();
- *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci);
if (rq_ci != rxq->rq_ci) {
rxq->rq_ci = rq_ci;
rte_io_wmb();
@@ -361,8 +359,6 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts,
rxq->decompressed -= n;
}
}
- rte_io_wmb();
- *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci);
*no_cq = !rcvd_pkt;
return rcvd_pkt;
}
@@ -390,6 +386,7 @@ mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
bool no_cq = false;
do {
+ err = 0;
nb_rx = rxq_burst_v(rxq, pkts + tn, pkts_n - tn,
&err, &no_cq);
if (unlikely(err | rxq->err_state))
@@ -397,6 +394,8 @@ mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
tn += nb_rx;
if (unlikely(no_cq))
break;
+ rte_io_wmb();
+ *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci);
} while (tn != pkts_n);
return tn;
}
@@ -524,6 +523,7 @@ mlx5_rx_burst_mprq_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
bool no_cq = false;
do {
+ err = 0;
nb_rx = rxq_burst_mprq_v(rxq, pkts + tn, pkts_n - tn,
&err, &no_cq);
if (unlikely(err | rxq->err_state))
@@ -531,6 +531,8 @@ mlx5_rx_burst_mprq_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
tn += nb_rx;
if (unlikely(no_cq))
break;
+ rte_io_wmb();
+ *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci);
} while (tn != pkts_n);
return tn;
}