OSDN Git Service

net/mlx5e: Enhance ICOSQ WQE info fields
authorAya Levin <ayal@mellanox.com>
Mon, 9 Mar 2020 07:44:18 +0000 (09:44 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Tue, 24 Mar 2020 21:43:00 +0000 (14:43 -0700)
Add number of WQEBBs (WQE's Basic Block) to WQE info struct. Set the
number of WQEBBs on WQE post, and increment the consumer counter (cc)
on completion.

In case of error completions, the cc was mistakenly not incremented,
keeping a gap between cc and pc (producer counter). This failed the
recovery flow on the ICOSQ from a CQE error which timed-out waiting for
the cc and pc to meet.

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_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c

index 220ef9f..571ac59 100644 (file)
@@ -371,6 +371,7 @@ enum {
 
 struct mlx5e_sq_wqe_info {
        u8  opcode;
+       u8 num_wqebbs;
 
        /* Auxiliary data for different opcodes. */
        union {
index 1c3ab69..312d469 100644 (file)
@@ -477,6 +477,7 @@ static inline void mlx5e_fill_icosq_frag_edge(struct mlx5e_icosq *sq,
        /* fill sq frag edge with nops to avoid wqe wrapping two pages */
        for (; wi < edge_wi; wi++) {
                wi->opcode = MLX5_OPCODE_NOP;
+               wi->num_wqebbs = 1;
                mlx5e_post_nop(wq, sq->sqn, &sq->pc);
        }
 }
@@ -525,6 +526,7 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
        umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset);
 
        sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_UMR;
+       sq->db.ico_wqe[pi].num_wqebbs = MLX5E_UMR_WQEBBS;
        sq->db.ico_wqe[pi].umr.rq = rq;
        sq->pc += MLX5E_UMR_WQEBBS;
 
@@ -621,6 +623,7 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
 
                        ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc);
                        wi = &sq->db.ico_wqe[ci];
+                       sqcc += wi->num_wqebbs;
 
                        if (last_wqe && unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) {
                                netdev_WARN_ONCE(cq->channel->netdev,
@@ -631,16 +634,12 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
                                break;
                        }
 
-                       if (likely(wi->opcode == MLX5_OPCODE_UMR)) {
-                               sqcc += MLX5E_UMR_WQEBBS;
+                       if (likely(wi->opcode == MLX5_OPCODE_UMR))
                                wi->umr.rq->mpwqe.umr_completed++;
-                       } else if (likely(wi->opcode == MLX5_OPCODE_NOP)) {
-                               sqcc++;
-                       } else {
+                       else if (unlikely(wi->opcode != MLX5_OPCODE_NOP))
                                netdev_WARN_ONCE(cq->channel->netdev,
                                                 "Bad OPCODE in ICOSQ WQE info: 0x%x\n",
                                                 wi->opcode);
-                       }
 
                } while (!last_wqe);
 
index 257a7c9..800d34e 100644 (file)
@@ -78,6 +78,7 @@ void mlx5e_trigger_irq(struct mlx5e_icosq *sq)
        u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
 
        sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP;
+       sq->db.ico_wqe[pi].num_wqebbs = 1;
        nopwqe = mlx5e_post_nop(wq, sq->sqn, &sq->pc);
        mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nopwqe->ctrl);
 }