4.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Tariq Toukan <tar...@mellanox.com>


[ Upstream commit 36154be40a28e4afaa0416da2681d80b7e2ca319 ]

In cqe compression with striding RQ, the decompression of the CQE field
wqe_counter was done with a wrong wraparound value.
This caused handling cqes with a wrong pointer to wqe (rx descriptor)
and creating SKBs with wrong data, pointing to wrong (and already consumed)
strides/pages.

The meaning of the CQE field wqe_counter in striding RQ holds the
stride index instead of the WQE index. Hence, when decompressing
a CQE, wqe_counter should have wrapped-around the number of strides
in a single multi-packet WQE.

We dropped this wrap-around mask at all in CQE decompression of striding
RQ. It is not needed as in such cases the CQE compression session would
break because of different value of wqe_id field, starting a new
compression session.

Tested:
 ethtool -K ethxx lro off/on
 ethtool --set-priv-flags ethxx rx_cqe_compress on
 super_netperf 16 {ipv4,ipv6} -t TCP_STREAM -m 50 -D
 verified no csum errors and no page refcount issues.

Fixes: 7219ab34f184 ("net/mlx5e: CQE compression")
Signed-off-by: Tariq Toukan <tar...@mellanox.com>
Reported-by: Tom Herbert <t...@herbertland.com>
Cc: kernel-t...@fb.com
Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -92,19 +92,18 @@ static inline void mlx5e_cqes_update_own
 static inline void mlx5e_decompress_cqe(struct mlx5e_rq *rq,
                                        struct mlx5e_cq *cq, u32 cqcc)
 {
-       u16 wqe_cnt_step;
-
        cq->title.byte_cnt     = cq->mini_arr[cq->mini_arr_idx].byte_cnt;
        cq->title.check_sum    = cq->mini_arr[cq->mini_arr_idx].checksum;
        cq->title.op_own      &= 0xf0;
        cq->title.op_own      |= 0x01 & (cqcc >> cq->wq.log_sz);
        cq->title.wqe_counter  = cpu_to_be16(cq->decmprs_wqe_counter);
 
-       wqe_cnt_step =
-               rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ?
-               mpwrq_get_cqe_consumed_strides(&cq->title) : 1;
-       cq->decmprs_wqe_counter =
-               (cq->decmprs_wqe_counter + wqe_cnt_step) & rq->wq.sz_m1;
+       if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
+               cq->decmprs_wqe_counter +=
+                       mpwrq_get_cqe_consumed_strides(&cq->title);
+       else
+               cq->decmprs_wqe_counter =
+                       (cq->decmprs_wqe_counter + 1) & rq->wq.sz_m1;
 }
 
 static inline void mlx5e_decompress_cqe_no_hash(struct mlx5e_rq *rq,


Reply via email to