diff options
author | Hariprasad S <hariprasad@chelsio.com> | 2016-05-04 15:57:33 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-05-05 16:11:14 -0400 |
commit | fef4422d00c135da4300d7d58e62cd0afe2af730 (patch) | |
tree | 7554f44850b7d69a5d2da8d482496f7768c711ed | |
parent | f8e1e1d13773e1bcad127cbb5be964d00ee1f682 (diff) |
RDMA/iw_cxgb4: free resources when send_flowc() fails
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index c4ce707d210b..864da9dec9f6 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -519,7 +519,7 @@ static void abort_arp_failure(void *handle, struct sk_buff *skb) | |||
519 | c4iw_ofld_send(rdev, skb); | 519 | c4iw_ofld_send(rdev, skb); |
520 | } | 520 | } |
521 | 521 | ||
522 | static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) | 522 | static int send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) |
523 | { | 523 | { |
524 | unsigned int flowclen = 80; | 524 | unsigned int flowclen = 80; |
525 | struct fw_flowc_wr *flowc; | 525 | struct fw_flowc_wr *flowc; |
@@ -575,7 +575,7 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) | |||
575 | } | 575 | } |
576 | 576 | ||
577 | set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx); | 577 | set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx); |
578 | c4iw_ofld_send(&ep->com.dev->rdev, skb); | 578 | return c4iw_ofld_send(&ep->com.dev->rdev, skb); |
579 | } | 579 | } |
580 | 580 | ||
581 | static int send_halfclose(struct c4iw_ep *ep, gfp_t gfp) | 581 | static int send_halfclose(struct c4iw_ep *ep, gfp_t gfp) |
@@ -1119,6 +1119,7 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1119 | unsigned int tid = GET_TID(req); | 1119 | unsigned int tid = GET_TID(req); |
1120 | unsigned int atid = TID_TID_G(ntohl(req->tos_atid)); | 1120 | unsigned int atid = TID_TID_G(ntohl(req->tos_atid)); |
1121 | struct tid_info *t = dev->rdev.lldi.tids; | 1121 | struct tid_info *t = dev->rdev.lldi.tids; |
1122 | int ret; | ||
1122 | 1123 | ||
1123 | ep = lookup_atid(t, atid); | 1124 | ep = lookup_atid(t, atid); |
1124 | 1125 | ||
@@ -1144,13 +1145,20 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1144 | set_bit(ACT_ESTAB, &ep->com.history); | 1145 | set_bit(ACT_ESTAB, &ep->com.history); |
1145 | 1146 | ||
1146 | /* start MPA negotiation */ | 1147 | /* start MPA negotiation */ |
1147 | send_flowc(ep, NULL); | 1148 | ret = send_flowc(ep, NULL); |
1149 | if (ret) | ||
1150 | goto err; | ||
1148 | if (ep->retry_with_mpa_v1) | 1151 | if (ep->retry_with_mpa_v1) |
1149 | send_mpa_req(ep, skb, 1); | 1152 | send_mpa_req(ep, skb, 1); |
1150 | else | 1153 | else |
1151 | send_mpa_req(ep, skb, mpa_rev); | 1154 | send_mpa_req(ep, skb, mpa_rev); |
1152 | mutex_unlock(&ep->com.mutex); | 1155 | mutex_unlock(&ep->com.mutex); |
1153 | return 0; | 1156 | return 0; |
1157 | err: | ||
1158 | mutex_unlock(&ep->com.mutex); | ||
1159 | connect_reply_upcall(ep, -ENOMEM); | ||
1160 | c4iw_ep_disconnect(ep, 0, GFP_KERNEL); | ||
1161 | return 0; | ||
1154 | } | 1162 | } |
1155 | 1163 | ||
1156 | static void close_complete_upcall(struct c4iw_ep *ep, int status) | 1164 | static void close_complete_upcall(struct c4iw_ep *ep, int status) |
@@ -2548,6 +2556,7 @@ static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
2548 | struct cpl_pass_establish *req = cplhdr(skb); | 2556 | struct cpl_pass_establish *req = cplhdr(skb); |
2549 | struct tid_info *t = dev->rdev.lldi.tids; | 2557 | struct tid_info *t = dev->rdev.lldi.tids; |
2550 | unsigned int tid = GET_TID(req); | 2558 | unsigned int tid = GET_TID(req); |
2559 | int ret; | ||
2551 | 2560 | ||
2552 | ep = lookup_tid(t, tid); | 2561 | ep = lookup_tid(t, tid); |
2553 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 2562 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
@@ -2560,10 +2569,14 @@ static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
2560 | set_emss(ep, ntohs(req->tcp_opt)); | 2569 | set_emss(ep, ntohs(req->tcp_opt)); |
2561 | 2570 | ||
2562 | dst_confirm(ep->dst); | 2571 | dst_confirm(ep->dst); |
2563 | state_set(&ep->com, MPA_REQ_WAIT); | 2572 | mutex_lock(&ep->com.mutex); |
2573 | ep->com.state = MPA_REQ_WAIT; | ||
2564 | start_ep_timer(ep); | 2574 | start_ep_timer(ep); |
2565 | send_flowc(ep, skb); | ||
2566 | set_bit(PASS_ESTAB, &ep->com.history); | 2575 | set_bit(PASS_ESTAB, &ep->com.history); |
2576 | ret = send_flowc(ep, skb); | ||
2577 | mutex_unlock(&ep->com.mutex); | ||
2578 | if (ret) | ||
2579 | c4iw_ep_disconnect(ep, 1, GFP_KERNEL); | ||
2567 | 2580 | ||
2568 | return 0; | 2581 | return 0; |
2569 | } | 2582 | } |