[dpdk-dev] [PATCH 2/4] net/mlx5: fixed used initialization in rx_queue_count

Maxime Leroy maxime.leroy at 6wind.com
Tue Nov 10 15:09:36 CET 2020


Mini (compressed) completion queue entries (CQEs) are returned by the
NIC when PCI back pressure is detected, in which case the first CQE64
contains common packet information followed by a number of CQE8
providing the rest, followed by a matching number of empty CQE64
entries to be used by software for decompression.

CQE already decompressed in software are not used/holded anymore by the
nic.

In the rx_queue_count function, if rx poll function has already started
to decompress some CQes. We need to count the number of CQEs not yet
decompressed, this CQEs are still holded by the hardware.

The context of the CQEs decompression is stored in the zip structure.
To get the number of cpe not decompressed yet (i.e. still holded by
the hadware), the following formula is used: zip->cqe_cnt - zip->ca in
rx_queue_count function.

The zip->cqe_cnt is the number of CQes compressed and zip->ca is the
current index of the cqe to decompress.

Thus, we can easily have cqe_cnt < ca. So this method to compute the
number of cqes still holded by the hardware is wrong.

The proper way to get the number of cqes not yet decrompressed is:

 - First, we need to know the current packet index to decompress:
   zip->ca + zip->ai. In the example below, the current packet index is
   2.

 - Then the index of the last packet index to decompress:
   zip->ci + zip->cqe_cnt. In the example below, the last packet index
   is 3.

- Thus the number of packets used by the hardware (i.e. not decompress
  yet) is: (zip->ci + zip->cqe_cnt) - (zip->ca + zip->ai). In the
  example below, the number of packets used by the hardware for the current
  cqe in decompression is 1.

::

       zip->cq_ci = 0  /* Current CQE */
       zip->ca = 1 /* Current array index for decompression */
       zip->ai = 1 /* array index in the mini cqe table in CQE1 below */
       zip->cqe_cnt = 3 /* number of CQEs set in the first CQE */

          0              1          2           6            7
      +---------+  +---------+ +-------+   +---------+   +-------+
      | CQE64   |  |  CQE64  | | CQE64 |   | CQE64   |   | CQE64 |
      |---------|  |---------| |-------|   |-------  |   |-------|
      |cqe_cnt=3|  | cqe8[0] | |       | . |cqe_cnt=X|   |cqe8[0]|
      | .....   |  | cqe8[1] | |       | . |         |   |  ...  | ...
      | .....   |  | cqe8[2] | |       | . |         |   |       |
      | .....   |  |         | |       |   |         |   |       |
      +---------+  +---------+ +-------+   +-------+++   +-------+

Fixes: 8788fec1f269 ("net/mlx5: implement descriptor status API")
Signed-off-by: Maxime Leroy <maxime.leroy at 6wind.com>
Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro at 6wind.com>
---
 drivers/net/mlx5/mlx5_rxtx.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index 4c566486..511003d1 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -464,13 +464,15 @@ rx_queue_count(struct mlx5_rxq_data *rxq)
 	volatile struct mlx5_cqe *cqe;
 	const unsigned int cqe_n = (1 << rxq->cqe_n);
 	const unsigned int cqe_cnt = cqe_n - 1;
-	unsigned int cq_ci;
+	unsigned int cq_ci, cq_end, cq_cur;
 	unsigned int used;
 
 	/* if we are processing a compressed cqe */
 	if (zip->ai) {
-		used = zip->cqe_cnt - zip->ca;
 		cq_ci = zip->cq_ci;
+		cq_end = cq_ci + zip->cqe_cnt;
+		cq_cur = zip->ca + zip->ai;
+		used = cq_end - cq_cur;
 	} else {
 		used = 0;
 		cq_ci = rxq->cq_ci;
-- 
2.27.0



More information about the dev mailing list