diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c index e912e5396e8c..6769a075501e 100644 --- a/drivers/infiniband/sw/rxe/rxe_comp.c +++ b/drivers/infiniband/sw/rxe/rxe_comp.c @@ -503,6 +503,26 @@ static inline enum comp_state complete_wqe(struct rxe_qp *qp, return COMPST_GET_WQE; } +static void rxe_drain_resp_pkts(struct rxe_qp *qp, bool notify) +{ + struct sk_buff *skb; + struct rxe_send_wqe *wqe; + + while ((skb = skb_dequeue(&qp->resp_pkts))) { + rxe_drop_ref(qp); + kfree_skb(skb); + } + + while ((wqe = queue_head(qp->sq.queue))) { + if (notify) { + wqe->status = IB_WC_WR_FLUSH_ERR; + do_complete(qp, wqe); + } else { + advance_consumer(qp->sq.queue); + } + } +} + int rxe_completer(void *arg) { struct rxe_qp *qp = (struct rxe_qp *)arg; @@ -513,47 +533,10 @@ int rxe_completer(void *arg) rxe_add_ref(qp); - if (!qp->valid) { - while ((skb = skb_dequeue(&qp->resp_pkts))) { - rxe_drop_ref(qp); - kfree_skb(skb); - } - skb = NULL; - pkt = NULL; - - while (queue_head(qp->sq.queue)) - advance_consumer(qp->sq.queue); - - goto exit; - } - - if (qp->req.state == QP_STATE_ERROR) { - while ((skb = skb_dequeue(&qp->resp_pkts))) { - rxe_drop_ref(qp); - kfree_skb(skb); - } - skb = NULL; - pkt = NULL; - - while ((wqe = queue_head(qp->sq.queue))) { - wqe->status = IB_WC_WR_FLUSH_ERR; - do_complete(qp, wqe); - } - - goto exit; - } - - if (qp->req.state == QP_STATE_RESET) { - while ((skb = skb_dequeue(&qp->resp_pkts))) { - rxe_drop_ref(qp); - kfree_skb(skb); - } - skb = NULL; - pkt = NULL; - - while (queue_head(qp->sq.queue)) - advance_consumer(qp->sq.queue); - + if (!qp->valid || qp->req.state == QP_STATE_ERROR || + qp->req.state == QP_STATE_RESET) { + rxe_drain_resp_pkts(qp, qp->valid && + qp->req.state == QP_STATE_ERROR); goto exit; } diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index 6dbd069689fc..51c134dbc6c8 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -1207,6 +1207,19 @@ static enum resp_states do_class_d1e_error(struct rxe_qp *qp) } } +static void rxe_drain_req_pkts(struct rxe_qp *qp) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(&qp->req_pkts))) { + rxe_drop_ref(qp); + kfree_skb(skb); + } + + while (!qp->srq && qp->rq.queue && queue_head(qp->rq.queue)) + advance_consumer(qp->rq.queue); +} + int rxe_responder(void *arg) { struct rxe_qp *qp = (struct rxe_qp *)arg; @@ -1374,21 +1387,10 @@ int rxe_responder(void *arg) goto exit; - case RESPST_RESET: { - struct sk_buff *skb; - - while ((skb = skb_dequeue(&qp->req_pkts))) { - rxe_drop_ref(qp); - kfree_skb(skb); - } - - while (!qp->srq && qp->rq.queue && - queue_head(qp->rq.queue)) - advance_consumer(qp->rq.queue); - + case RESPST_RESET: + rxe_drain_req_pkts(qp); qp->resp.wqe = NULL; goto exit; - } case RESPST_ERROR: qp->resp.goto_error = 0;