net/mlx5e: Fix ICOSQ recovery flow with Striding RQ
In striding RQ mode, the buffers of an RX WQE are first
prepared and posted to the HW using a UMR WQEs via the ICOSQ.
We maintain the state of these in-progress WQEs in the RQ
SW struct.
In the flow of ICOSQ recovery, the corresponding RQ is not
in error state, hence:
- The buffers of the in-progress WQEs must be released
and the RQ metadata should reflect it.
- Existing RX WQEs in the RQ should not be affected.
For this, wrap the dealloc of the in-progress WQEs in
a function, and use it in the ICOSQ recovery flow
instead of mlx5e_free_rx_descs().
Fixes: be5323c837 ("net/mlx5e: Report and recover from CQE error on ICOSQ")
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
parent
39369fd536
commit
e239c6d686
3 changed files with 26 additions and 8 deletions
|
|
@ -1060,6 +1060,7 @@ int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_state);
|
|||
void mlx5e_activate_rq(struct mlx5e_rq *rq);
|
||||
void mlx5e_deactivate_rq(struct mlx5e_rq *rq);
|
||||
void mlx5e_free_rx_descs(struct mlx5e_rq *rq);
|
||||
void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq);
|
||||
void mlx5e_activate_icosq(struct mlx5e_icosq *icosq);
|
||||
void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ static int mlx5e_rx_reporter_err_icosq_cqe_recover(void *ctx)
|
|||
goto out;
|
||||
|
||||
mlx5e_reset_icosq_cc_pc(icosq);
|
||||
mlx5e_free_rx_descs(rq);
|
||||
mlx5e_free_rx_in_progress_descs(rq);
|
||||
clear_bit(MLX5E_SQ_STATE_RECOVERING, &icosq->state);
|
||||
mlx5e_activate_icosq(icosq);
|
||||
mlx5e_activate_rq(rq);
|
||||
|
|
|
|||
|
|
@ -813,6 +813,29 @@ int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq, int wait_time)
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq)
|
||||
{
|
||||
struct mlx5_wq_ll *wq;
|
||||
u16 head;
|
||||
int i;
|
||||
|
||||
if (rq->wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
|
||||
return;
|
||||
|
||||
wq = &rq->mpwqe.wq;
|
||||
head = wq->head;
|
||||
|
||||
/* Outstanding UMR WQEs (in progress) start at wq->head */
|
||||
for (i = 0; i < rq->mpwqe.umr_in_progress; i++) {
|
||||
rq->dealloc_wqe(rq, head);
|
||||
head = mlx5_wq_ll_get_wqe_next_ix(wq, head);
|
||||
}
|
||||
|
||||
rq->mpwqe.actual_wq_head = wq->head;
|
||||
rq->mpwqe.umr_in_progress = 0;
|
||||
rq->mpwqe.umr_completed = 0;
|
||||
}
|
||||
|
||||
void mlx5e_free_rx_descs(struct mlx5e_rq *rq)
|
||||
{
|
||||
__be16 wqe_ix_be;
|
||||
|
|
@ -820,14 +843,8 @@ void mlx5e_free_rx_descs(struct mlx5e_rq *rq)
|
|||
|
||||
if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
|
||||
struct mlx5_wq_ll *wq = &rq->mpwqe.wq;
|
||||
u16 head = wq->head;
|
||||
int i;
|
||||
|
||||
/* Outstanding UMR WQEs (in progress) start at wq->head */
|
||||
for (i = 0; i < rq->mpwqe.umr_in_progress; i++) {
|
||||
rq->dealloc_wqe(rq, head);
|
||||
head = mlx5_wq_ll_get_wqe_next_ix(wq, head);
|
||||
}
|
||||
mlx5e_free_rx_in_progress_descs(rq);
|
||||
|
||||
while (!mlx5_wq_ll_is_empty(wq)) {
|
||||
struct mlx5e_rx_wqe_ll *wqe;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue