IB/rxe: Generate a completion for all failed work requests
authorBart Van Assche <bart.vanassche@sandisk.com>
Tue, 10 Jan 2017 19:15:50 +0000 (11:15 -0800)
committerDoug Ledford <dledford@redhat.com>
Tue, 10 Jan 2017 21:52:47 +0000 (16:52 -0500)
Change do_complete() such that an error completion is not only
generated if a QP is in the error state but also if a work request
failed.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Andrew Boyer <andrew.boyer@dell.com>
Cc: Moni Shoua <monis@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/sw/rxe/rxe_comp.c
drivers/infiniband/sw/rxe/rxe_loc.h
drivers/infiniband/sw/rxe/rxe_req.c
drivers/infiniband/sw/rxe/rxe_resp.c

index 6769a075501ecdfc82b9722e3de2954758779c80..91317c159b9ade0b04dc09ab6aa5fa73ff5e461a 100644 (file)
@@ -412,13 +412,21 @@ static void make_send_cqe(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
        }
 }
 
+/*
+ * IBA Spec. Section 10.7.3.1 SIGNALED COMPLETIONS
+ * ---------8<---------8<-------------
+ * ...Note that if a completion error occurs, a Work Completion
+ * will always be generated, even if the signaling
+ * indicator requests an Unsignaled Completion.
+ * ---------8<---------8<-------------
+ */
 static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
 {
        struct rxe_cqe cqe;
 
        if ((qp->sq_sig_type == IB_SIGNAL_ALL_WR) ||
            (wqe->wr.send_flags & IB_SEND_SIGNALED) ||
-           (qp->req.state == QP_STATE_ERROR)) {
+           wqe->status != IB_WC_SUCCESS) {
                make_send_cqe(qp, wqe, &cqe);
                advance_consumer(qp->sq.queue);
                rxe_cq_post(qp->scq, &cqe, 0);
@@ -709,6 +717,7 @@ int rxe_completer(void *arg)
                        break;
 
                case COMPST_ERROR:
+                       WARN_ON_ONCE(wqe->status == IB_WC_SUCCESS);
                        do_complete(qp, wqe);
                        rxe_qp_error(qp);
 
index da191d7acb6fc3dbd556bbc12f842ee0564b8dd8..bdec460f1fcec2387d6fd8700ca19ce79072c743 100644 (file)
@@ -225,6 +225,7 @@ extern struct ib_dma_mapping_ops rxe_dma_mapping_ops;
 
 void rxe_release(struct kref *kref);
 
+void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify);
 int rxe_completer(void *arg);
 int rxe_requester(void *arg);
 int rxe_responder(void *arg);
index 310cd335057869c06a4e7265feac2d5645b9ae71..d62be4828899cf94a9a205f275ad25d6240145f3 100644 (file)
@@ -594,9 +594,14 @@ int rxe_requester(void *arg)
        rxe_add_ref(qp);
 
 next_wqe:
-       if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR))
+       if (unlikely(!qp->valid))
                goto exit;
 
+       if (unlikely(qp->req.state == QP_STATE_ERROR)) {
+               rxe_drain_req_pkts(qp, true);
+               goto exit;
+       }
+
        if (unlikely(qp->req.state == QP_STATE_RESET)) {
                qp->req.wqe_index = consumer_index(qp->sq.queue);
                qp->req.opcode = -1;
@@ -743,17 +748,8 @@ err:
        kfree_skb(skb);
        wqe->status = IB_WC_LOC_PROT_ERR;
        wqe->state = wqe_state_error;
-
-       /*
-        * IBA Spec. Section 10.7.3.1 SIGNALED COMPLETIONS
-        * ---------8<---------8<-------------
-        * ...Note that if a completion error occurs, a Work Completion
-        * will always be generated, even if the signaling
-        * indicator requests an Unsignaled Completion.
-        * ---------8<---------8<-------------
-        */
-       wqe->wr.send_flags |= IB_SEND_SIGNALED;
        __rxe_do_task(&qp->comp.task);
+
 exit:
        rxe_drop_ref(qp);
        return -EAGAIN;
index 51c134dbc6c83b7eb62d8027c7b10e8b812a6d13..33defaddc0008e0cd133df645644341d1849baa1 100644 (file)
@@ -1207,7 +1207,7 @@ static enum resp_states do_class_d1e_error(struct rxe_qp *qp)
        }
 }
 
-static void rxe_drain_req_pkts(struct rxe_qp *qp)
+void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify)
 {
        struct sk_buff *skb;
 
@@ -1388,7 +1388,7 @@ int rxe_responder(void *arg)
                        goto exit;
 
                case RESPST_RESET:
-                       rxe_drain_req_pkts(qp);
+                       rxe_drain_req_pkts(qp, false);
                        qp->resp.wqe = NULL;
                        goto exit;