OSDN Git Service

net/mlx5e: Fix ICOSQ recovery flow with Striding RQ
authorAya Levin <ayal@mellanox.com>
Mon, 16 Mar 2020 14:53:10 +0000 (16:53 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Tue, 24 Mar 2020 21:43:05 +0000 (14:43 -0700)
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: be5323c8379f ("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>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c

index 571ac59..c9606b8 100644 (file)
@@ -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);
 
index 6c72b59..a01e2de 100644 (file)
@@ -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);
index 21de476..4ef3dc7 100644 (file)
@@ -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;