aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2014-03-21 11:10:33 -0400
committerRoland Dreier <roland@purestorage.com>2014-03-24 13:07:35 -0400
commitbe13b2dff8c4e41846477b22cc5c164ea5a6ac2e (patch)
tree8a09ceb4e33ad0534c3e1bec64dddcae7e230363
parent70b9c66053ecadde421658b8ec808c981f2eef11 (diff)
RDMA/cxgb4: Connect_request_upcall fixes
When processing an MPA Start Request, if the listening endpoint is DEAD, then abort the connection. If the IWCM returns an error, then we must abort the connection and release resources. Also abort_connection() should not post a CLOSE event, so clean that up too. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 773d010a249c..6bfef31f6b1e 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -968,13 +968,14 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
968 return 0; 968 return 0;
969} 969}
970 970
971static void close_complete_upcall(struct c4iw_ep *ep) 971static void close_complete_upcall(struct c4iw_ep *ep, int status)
972{ 972{
973 struct iw_cm_event event; 973 struct iw_cm_event event;
974 974
975 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); 975 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
976 memset(&event, 0, sizeof(event)); 976 memset(&event, 0, sizeof(event));
977 event.event = IW_CM_EVENT_CLOSE; 977 event.event = IW_CM_EVENT_CLOSE;
978 event.status = status;
978 if (ep->com.cm_id) { 979 if (ep->com.cm_id) {
979 PDBG("close complete delivered ep %p cm_id %p tid %u\n", 980 PDBG("close complete delivered ep %p cm_id %p tid %u\n",
980 ep, ep->com.cm_id, ep->hwtid); 981 ep, ep->com.cm_id, ep->hwtid);
@@ -988,7 +989,6 @@ static void close_complete_upcall(struct c4iw_ep *ep)
988static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) 989static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
989{ 990{
990 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); 991 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
991 close_complete_upcall(ep);
992 state_set(&ep->com, ABORTING); 992 state_set(&ep->com, ABORTING);
993 set_bit(ABORT_CONN, &ep->com.history); 993 set_bit(ABORT_CONN, &ep->com.history);
994 return send_abort(ep, skb, gfp); 994 return send_abort(ep, skb, gfp);
@@ -1067,9 +1067,10 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status)
1067 } 1067 }
1068} 1068}
1069 1069
1070static void connect_request_upcall(struct c4iw_ep *ep) 1070static int connect_request_upcall(struct c4iw_ep *ep)
1071{ 1071{
1072 struct iw_cm_event event; 1072 struct iw_cm_event event;
1073 int ret;
1073 1074
1074 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); 1075 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1075 memset(&event, 0, sizeof(event)); 1076 memset(&event, 0, sizeof(event));
@@ -1094,15 +1095,14 @@ static void connect_request_upcall(struct c4iw_ep *ep)
1094 event.private_data_len = ep->plen; 1095 event.private_data_len = ep->plen;
1095 event.private_data = ep->mpa_pkt + sizeof(struct mpa_message); 1096 event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);
1096 } 1097 }
1097 if (state_read(&ep->parent_ep->com) != DEAD) { 1098 c4iw_get_ep(&ep->com);
1098 c4iw_get_ep(&ep->com); 1099 ret = ep->parent_ep->com.cm_id->event_handler(ep->parent_ep->com.cm_id,
1099 ep->parent_ep->com.cm_id->event_handler( 1100 &event);
1100 ep->parent_ep->com.cm_id, 1101 if (ret)
1101 &event); 1102 c4iw_put_ep(&ep->com);
1102 }
1103 set_bit(CONNREQ_UPCALL, &ep->com.history); 1103 set_bit(CONNREQ_UPCALL, &ep->com.history);
1104 c4iw_put_ep(&ep->parent_ep->com); 1104 c4iw_put_ep(&ep->parent_ep->com);
1105 ep->parent_ep = NULL; 1105 return ret;
1106} 1106}
1107 1107
1108static void established_upcall(struct c4iw_ep *ep) 1108static void established_upcall(struct c4iw_ep *ep)
@@ -1401,7 +1401,6 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
1401 return; 1401 return;
1402 1402
1403 PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__); 1403 PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);
1404 stop_ep_timer(ep);
1405 mpa = (struct mpa_message *) ep->mpa_pkt; 1404 mpa = (struct mpa_message *) ep->mpa_pkt;
1406 1405
1407 /* 1406 /*
@@ -1494,9 +1493,17 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
1494 ep->mpa_attr.p2p_type); 1493 ep->mpa_attr.p2p_type);
1495 1494
1496 state_set(&ep->com, MPA_REQ_RCVD); 1495 state_set(&ep->com, MPA_REQ_RCVD);
1496 stop_ep_timer(ep);
1497 1497
1498 /* drive upcall */ 1498 /* drive upcall */
1499 connect_request_upcall(ep); 1499 mutex_lock(&ep->parent_ep->com.mutex);
1500 if (ep->parent_ep->com.state != DEAD) {
1501 if (connect_request_upcall(ep))
1502 abort_connection(ep, skb, GFP_KERNEL);
1503 } else {
1504 abort_connection(ep, skb, GFP_KERNEL);
1505 }
1506 mutex_unlock(&ep->parent_ep->com.mutex);
1500 return; 1507 return;
1501} 1508}
1502 1509
@@ -2247,7 +2254,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
2247 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, 2254 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
2248 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); 2255 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
2249 } 2256 }
2250 close_complete_upcall(ep); 2257 close_complete_upcall(ep, 0);
2251 __state_set(&ep->com, DEAD); 2258 __state_set(&ep->com, DEAD);
2252 release = 1; 2259 release = 1;
2253 disconnect = 0; 2260 disconnect = 0;
@@ -2426,7 +2433,7 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2426 C4IW_QP_ATTR_NEXT_STATE, 2433 C4IW_QP_ATTR_NEXT_STATE,
2427 &attrs, 1); 2434 &attrs, 1);
2428 } 2435 }
2429 close_complete_upcall(ep); 2436 close_complete_upcall(ep, 0);
2430 __state_set(&ep->com, DEAD); 2437 __state_set(&ep->com, DEAD);
2431 release = 1; 2438 release = 1;
2432 break; 2439 break;
@@ -2981,7 +2988,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
2981 rdev = &ep->com.dev->rdev; 2988 rdev = &ep->com.dev->rdev;
2982 if (c4iw_fatal_error(rdev)) { 2989 if (c4iw_fatal_error(rdev)) {
2983 fatal = 1; 2990 fatal = 1;
2984 close_complete_upcall(ep); 2991 close_complete_upcall(ep, -EIO);
2985 ep->com.state = DEAD; 2992 ep->com.state = DEAD;
2986 } 2993 }
2987 switch (ep->com.state) { 2994 switch (ep->com.state) {
@@ -3023,7 +3030,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
3023 if (close) { 3030 if (close) {
3024 if (abrupt) { 3031 if (abrupt) {
3025 set_bit(EP_DISC_ABORT, &ep->com.history); 3032 set_bit(EP_DISC_ABORT, &ep->com.history);
3026 close_complete_upcall(ep); 3033 close_complete_upcall(ep, -ECONNRESET);
3027 ret = send_abort(ep, NULL, gfp); 3034 ret = send_abort(ep, NULL, gfp);
3028 } else { 3035 } else {
3029 set_bit(EP_DISC_CLOSE, &ep->com.history); 3036 set_bit(EP_DISC_CLOSE, &ep->com.history);
@@ -3435,6 +3442,7 @@ static void process_timeout(struct c4iw_ep *ep)
3435 &attrs, 1); 3442 &attrs, 1);
3436 } 3443 }
3437 __state_set(&ep->com, ABORTING); 3444 __state_set(&ep->com, ABORTING);
3445 close_complete_upcall(ep, -ETIMEDOUT);
3438 break; 3446 break;
3439 default: 3447 default:
3440 WARN(1, "%s unexpected state ep %p tid %u state %u\n", 3448 WARN(1, "%s unexpected state ep %p tid %u state %u\n",