diff options
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 20 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 |
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); | |||
143 | static LIST_HEAD(timeout_list); | 143 | static LIST_HEAD(timeout_list); |
144 | static spinlock_t timeout_lock; | 144 | static spinlock_t timeout_lock; |
145 | 145 | ||
146 | static 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 | |||
152 | static 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 | |||
146 | static void start_ep_timer(struct c4iw_ep *ep) | 158 | static 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; |
2465 | err1: | 2477 | err1: |
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); |
2469 | err: | 2480 | err: |
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 | ||
721 | enum c4iw_ep_history { | 722 | enum c4iw_ep_history { |