RDMA/iw_cxgb4: Handle return value of c4iw_ofld_send() in abort_arp_failure()
authorHariprasad S <hariprasad@chelsio.com>
Fri, 6 May 2016 16:48:02 +0000 (22:18 +0530)
committerDoug Ledford <dledford@redhat.com>
Fri, 13 May 2016 23:38:07 +0000 (19:38 -0400)
In abort_arp_failure(), the return value from c4iw_ofld_send() is
ignored and thus if the CPL isn't sent, the endpoint is stuck and never
gets aborted. Failure of c4iw_ofld_send() is treated as fatal error, and
the ep resources are released in a safer context through process_work().

Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/cxgb4/cm.c

index 6c22bc95a11227ddee89cd1fd01adc3e4490e4e0..6129dbd0dc9e2dd283df61f0a8f3bcd820d06486 100644 (file)
@@ -540,12 +540,18 @@ static void act_open_req_arp_failure(void *handle, struct sk_buff *skb)
  */
 static void abort_arp_failure(void *handle, struct sk_buff *skb)
 {
-       struct c4iw_rdev *rdev = handle;
+       int ret;
+       struct c4iw_ep *ep = handle;
+       struct c4iw_rdev *rdev = &ep->com.dev->rdev;
        struct cpl_abort_req *req = cplhdr(skb);
 
        PDBG("%s rdev %p\n", __func__, rdev);
        req->cmd = CPL_ABORT_NO_RST;
-       c4iw_ofld_send(rdev, skb);
+       ret = c4iw_ofld_send(rdev, skb);
+       if (ret) {
+               __state_set(&ep->com, DEAD);
+               queue_arp_failure_cpl(ep, skb, FAKE_CPL_PUT_EP_SAFE);
+       }
 }
 
 static int send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
@@ -642,7 +648,7 @@ static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
                return -ENOMEM;
        }
        set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
-       t4_set_arp_err_handler(skb, &ep->com.dev->rdev, abort_arp_failure);
+       t4_set_arp_err_handler(skb, ep, abort_arp_failure);
        req = (struct cpl_abort_req *) skb_put(skb, wrlen);
        memset(req, 0, wrlen);
        INIT_TP_WR(req, ep->hwtid);