Skip to content

Commit c058ecf

Browse files
Steve Wisejgunthorpe
authored andcommitted
iw_cxgb4: only insert drain cqes if wq is flushed
Only insert our special drain CQEs to support ib_drain_sq/rq() after the wq is flushed. Otherwise, existing but not yet polled CQEs can be returned out of order to the user application. This can happen when the QP has exited RTS but not yet flushed the QP, which can happen during a normal close (vs abortive close). In addition never count the drain CQEs when determining how many CQEs need to be synthesized during the flush operation. This latter issue should never happen if the QP is properly flushed before inserting the drain CQE, but I wanted to avoid corrupting the CQ state. So we handle it and log a warning once. Fixes: 4fe7c29 ("iw_cxgb4: refactor sq/rq drain logic") Signed-off-by: Steve Wise <[email protected]> Cc: [email protected] Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 335ebf6 commit c058ecf

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

drivers/infiniband/hw/cxgb4/cq.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp)
395395

396396
static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq)
397397
{
398+
if (CQE_OPCODE(cqe) == C4IW_DRAIN_OPCODE) {
399+
WARN_ONCE(1, "Unexpected DRAIN CQE qp id %u!\n", wq->sq.qid);
400+
return 0;
401+
}
402+
398403
if (CQE_OPCODE(cqe) == FW_RI_TERMINATE)
399404
return 0;
400405

drivers/infiniband/hw/cxgb4/qp.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,12 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
868868

869869
qhp = to_c4iw_qp(ibqp);
870870
spin_lock_irqsave(&qhp->lock, flag);
871-
if (t4_wq_in_error(&qhp->wq)) {
871+
872+
/*
873+
* If the qp has been flushed, then just insert a special
874+
* drain cqe.
875+
*/
876+
if (qhp->wq.flushed) {
872877
spin_unlock_irqrestore(&qhp->lock, flag);
873878
complete_sq_drain_wr(qhp, wr);
874879
return err;
@@ -1011,7 +1016,12 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
10111016

10121017
qhp = to_c4iw_qp(ibqp);
10131018
spin_lock_irqsave(&qhp->lock, flag);
1014-
if (t4_wq_in_error(&qhp->wq)) {
1019+
1020+
/*
1021+
* If the qp has been flushed, then just insert a special
1022+
* drain cqe.
1023+
*/
1024+
if (qhp->wq.flushed) {
10151025
spin_unlock_irqrestore(&qhp->lock, flag);
10161026
complete_rq_drain_wr(qhp, wr);
10171027
return err;

0 commit comments

Comments
 (0)