aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2007-06-18 11:13:59 -0400
committerRoland Dreier <rolandd@cisco.com>2007-06-18 11:13:59 -0400
commit082dee3216c99a838af40be403799f60bcea2e97 (patch)
tree4741bc693e9eb882e5c72ab2d206cbe63e9dafaa /drivers/infiniband/hw
parent54e95f8dcbd7d86f79b423e8d11053ec9a2d9946 (diff)
IB/mlx4: Handle buffer wraparound in __mlx4_ib_cq_clean()
When compacting CQ entries, we need to set the correct value of the ownership bit in case the value is different between the index we copy the CQE from and the index we copy it to. Found by Ronni Zimmerman of Mellanox. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index e940521e9c8d..660b27aecae5 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -478,7 +478,8 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
478{ 478{
479 u32 prod_index; 479 u32 prod_index;
480 int nfreed = 0; 480 int nfreed = 0;
481 struct mlx4_cqe *cqe; 481 struct mlx4_cqe *cqe, *dest;
482 u8 owner_bit;
482 483
483 /* 484 /*
484 * First we need to find the current producer index, so we 485 * First we need to find the current producer index, so we
@@ -501,9 +502,13 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
501 if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK)) 502 if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK))
502 mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index)); 503 mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index));
503 ++nfreed; 504 ++nfreed;
504 } else if (nfreed) 505 } else if (nfreed) {
505 memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe), 506 dest = get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe);
506 cqe, sizeof *cqe); 507 owner_bit = dest->owner_sr_opcode & MLX4_CQE_OWNER_MASK;
508 memcpy(dest, cqe, sizeof *cqe);
509 dest->owner_sr_opcode = owner_bit |
510 (dest->owner_sr_opcode & ~MLX4_CQE_OWNER_MASK);
511 }
507 } 512 }
508 513
509 if (nfreed) { 514 if (nfreed) {