mlx5: Fix signed-overflow UB in __mlx5_cq_clean() sweep condition

[ Upstream commit 2dc29c114f5765758cf3695ab3c428e05bb133c7 ]

The backward sweep in __mlx5_cq_clean() used:

  while ((int) --prod_index - (int) cq->cons_index >= 0)

Both operands are uint32_t.  Promoting them to int and then subtracting
is undefined behaviour when the result overflows (C11 ยง6.5p5).  GCC and
Clang exploit that UB: they fold "(int)a - (int)b >= 0" into the plain
signed compare "(int)a >= (int)b", which has no exit when cons_index is
0x80000000 (INT_MIN), causing an infinite loop with the CQ spinlock held.
Every other thread polling that CQ blocks; the kernel-side QP is already
destroyed, so the process must be killed to recover.  A long-lived process
sharing one CQ across many short-lived QPs hits this every 2^32
completions (~90 s at 24 M CQE/s, ~10 days at 2.4 k CQE/s).

Replace with a plain unsigned equality check:

  while (prod_index != cq->cons_index) { --prod_index; ... }

prod_index starts at the value found by the forward scan, which begins
at cons_index and only increments, so prod_index >= cons_index always
holds.  Decrementing prod_index each iteration reaches cons_index in
exactly (prod_index - cons_index) steps.  No arithmetic on the loop
condition, no signed casts, no compiler-visible UB.

Fixes: 8c4791ae2395 ("libmlx5: First version of libmlx5")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Signed-off-by: Nicolas Morey <nmorey@suse.com>
diff --git a/providers/mlx5/cq.c b/providers/mlx5/cq.c
index 2bb2b58..f0bd5be 100644
--- a/providers/mlx5/cq.c
+++ b/providers/mlx5/cq.c
@@ -1842,7 +1842,8 @@
 	 * that match our QP by copying older entries on top of them.
 	 */
 	cqe_version = (to_mctx(cq->verbs_cq.cq.context))->cqe_version;
-	while ((int) --prod_index - (int) cq->cons_index >= 0) {
+	while (prod_index != cq->cons_index) {
+		--prod_index;
 		cqe = get_cqe(cq, prod_index & cq->verbs_cq.cq.cqe);
 		cqe64 = (cq->cqe_sz == 64) ? cqe : cqe + 64;
 		if (free_res_cqe(cqe64, rsn, srq, cqe_version)) {