aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c20
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h1
2 files changed, 17 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 31d1fac605d3..ebcdb3ff0cf4 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -143,6 +143,18 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status);
143static LIST_HEAD(timeout_list); 143static LIST_HEAD(timeout_list);
144static spinlock_t timeout_lock; 144static spinlock_t timeout_lock;
145 145
146static void deref_qp(struct c4iw_ep *ep)
147{
148 c4iw_qp_rem_ref(&ep->com.qp->ibqp);
149 clear_bit(QP_REFERENCED, &ep->com.flags);
150}
151
152static void ref_qp(struct c4iw_ep *ep)
153{
154 set_bit(QP_REFERENCED, &ep->com.flags);
155 c4iw_qp_add_ref(&ep->com.qp->ibqp);
156}
157
146static void start_ep_timer(struct c4iw_ep *ep) 158static void start_ep_timer(struct c4iw_ep *ep)
147{ 159{
148 PDBG("%s ep %p\n", __func__, ep); 160 PDBG("%s ep %p\n", __func__, ep);
@@ -271,6 +283,8 @@ void _c4iw_free_ep(struct kref *kref)
271 283
272 ep = container_of(kref, struct c4iw_ep, com.kref); 284 ep = container_of(kref, struct c4iw_ep, com.kref);
273 PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]); 285 PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
286 if (test_bit(QP_REFERENCED, &ep->com.flags))
287 deref_qp(ep);
274 if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) { 288 if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {
275 cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid); 289 cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid);
276 dst_release(ep->dst); 290 dst_release(ep->dst);
@@ -863,7 +877,6 @@ static void close_complete_upcall(struct c4iw_ep *ep)
863 ep->com.cm_id->event_handler(ep->com.cm_id, &event); 877 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
864 ep->com.cm_id->rem_ref(ep->com.cm_id); 878 ep->com.cm_id->rem_ref(ep->com.cm_id);
865 ep->com.cm_id = NULL; 879 ep->com.cm_id = NULL;
866 ep->com.qp = NULL;
867 set_bit(CLOSE_UPCALL, &ep->com.history); 880 set_bit(CLOSE_UPCALL, &ep->com.history);
868 } 881 }
869} 882}
@@ -906,7 +919,6 @@ static void peer_abort_upcall(struct c4iw_ep *ep)
906 ep->com.cm_id->event_handler(ep->com.cm_id, &event); 919 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
907 ep->com.cm_id->rem_ref(ep->com.cm_id); 920 ep->com.cm_id->rem_ref(ep->com.cm_id);
908 ep->com.cm_id = NULL; 921 ep->com.cm_id = NULL;
909 ep->com.qp = NULL;
910 set_bit(ABORT_UPCALL, &ep->com.history); 922 set_bit(ABORT_UPCALL, &ep->com.history);
911 } 923 }
912} 924}
@@ -946,7 +958,6 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status)
946 if (status < 0) { 958 if (status < 0) {
947 ep->com.cm_id->rem_ref(ep->com.cm_id); 959 ep->com.cm_id->rem_ref(ep->com.cm_id);
948 ep->com.cm_id = NULL; 960 ep->com.cm_id = NULL;
949 ep->com.qp = NULL;
950 } 961 }
951} 962}
952 963
@@ -2434,6 +2445,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2434 cm_id->add_ref(cm_id); 2445 cm_id->add_ref(cm_id);
2435 ep->com.cm_id = cm_id; 2446 ep->com.cm_id = cm_id;
2436 ep->com.qp = qp; 2447 ep->com.qp = qp;
2448 ref_qp(ep);
2437 2449
2438 /* bind QP to EP and move to RTS */ 2450 /* bind QP to EP and move to RTS */
2439 attrs.mpa_attr = ep->mpa_attr; 2451 attrs.mpa_attr = ep->mpa_attr;
@@ -2464,7 +2476,6 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2464 return 0; 2476 return 0;
2465err1: 2477err1:
2466 ep->com.cm_id = NULL; 2478 ep->com.cm_id = NULL;
2467 ep->com.qp = NULL;
2468 cm_id->rem_ref(cm_id); 2479 cm_id->rem_ref(cm_id);
2469err: 2480err:
2470 c4iw_put_ep(&ep->com); 2481 c4iw_put_ep(&ep->com);
@@ -2505,6 +2516,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2505 ep->com.cm_id = cm_id; 2516 ep->com.cm_id = cm_id;
2506 ep->com.qp = get_qhp(dev, conn_param->qpn); 2517 ep->com.qp = get_qhp(dev, conn_param->qpn);
2507 BUG_ON(!ep->com.qp); 2518 BUG_ON(!ep->com.qp);
2519 ref_qp(ep);
2508 PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn, 2520 PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn,
2509 ep->com.qp, cm_id); 2521 ep->com.qp, cm_id);
2510 2522
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 9c1644fb0259..0aaaa0e81f29 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -716,6 +716,7 @@ enum c4iw_ep_flags {
716 ABORT_REQ_IN_PROGRESS = 1, 716 ABORT_REQ_IN_PROGRESS = 1,
717 RELEASE_RESOURCES = 2, 717 RELEASE_RESOURCES = 2,
718 CLOSE_SENT = 3, 718 CLOSE_SENT = 3,
719 QP_REFERENCED = 5,
719}; 720};
720 721
721enum c4iw_ep_history { 722enum c4iw_ep_history {