Skip to content

Commit 2df19e1

Browse files
bharatpotnuridledford
authored andcommitted
iw_cxgb4: Atomically flush per QP HW CQEs
When a CQ is shared by multiple QPs, c4iw_flush_hw_cq() needs to acquire corresponding QP lock before moving the CQEs into its corresponding SW queue and accessing the SQ contents for completing a WR. Ignore CQEs if corresponding QP is already flushed. Cc: [email protected] Signed-off-by: Potnuri Bharat Teja <[email protected]> Reviewed-by: Steve Wise <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 54e7e48 commit 2df19e1

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

drivers/infiniband/hw/cxgb4/cq.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ static void advance_oldest_read(struct t4_wq *wq)
315315
* Deal with out-of-order and/or completions that complete
316316
* prior unsignalled WRs.
317317
*/
318-
void c4iw_flush_hw_cq(struct c4iw_cq *chp)
318+
void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp)
319319
{
320320
struct t4_cqe *hw_cqe, *swcqe, read_cqe;
321321
struct c4iw_qp *qhp;
@@ -339,6 +339,13 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp)
339339
if (qhp == NULL)
340340
goto next_cqe;
341341

342+
if (flush_qhp != qhp) {
343+
spin_lock(&qhp->lock);
344+
345+
if (qhp->wq.flushed == 1)
346+
goto next_cqe;
347+
}
348+
342349
if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE)
343350
goto next_cqe;
344351

@@ -390,6 +397,8 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp)
390397
next_cqe:
391398
t4_hwcq_consume(&chp->cq);
392399
ret = t4_next_hw_cqe(&chp->cq, &hw_cqe);
400+
if (qhp && flush_qhp != qhp)
401+
spin_unlock(&qhp->lock);
393402
}
394403
}
395404

drivers/infiniband/hw/cxgb4/iw_cxgb4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size);
10531053
void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size);
10541054
u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size);
10551055
void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size);
1056-
void c4iw_flush_hw_cq(struct c4iw_cq *chp);
1056+
void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp);
10571057
void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count);
10581058
int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp);
10591059
int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count);

drivers/infiniband/hw/cxgb4/qp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,12 +1343,12 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp,
13431343
qhp->wq.flushed = 1;
13441344
t4_set_wq_in_error(&qhp->wq);
13451345

1346-
c4iw_flush_hw_cq(rchp);
1346+
c4iw_flush_hw_cq(rchp, qhp);
13471347
c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count);
13481348
rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count);
13491349

13501350
if (schp != rchp)
1351-
c4iw_flush_hw_cq(schp);
1351+
c4iw_flush_hw_cq(schp, qhp);
13521352
sq_flushed = c4iw_flush_sq(qhp);
13531353

13541354
spin_unlock(&qhp->lock);

0 commit comments

Comments
 (0)