diff options
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 52 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.h | 9 |
2 files changed, 33 insertions, 28 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 52d7bb0c2a1..7f22f179771 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
| @@ -286,7 +286,7 @@ void __free_ep(struct kref *kref) | |||
| 286 | ep = container_of(container_of(kref, struct iwch_ep_common, kref), | 286 | ep = container_of(container_of(kref, struct iwch_ep_common, kref), |
| 287 | struct iwch_ep, com); | 287 | struct iwch_ep, com); |
| 288 | PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]); | 288 | PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]); |
| 289 | if (ep->com.flags & RELEASE_RESOURCES) { | 289 | if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) { |
| 290 | cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); | 290 | cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); |
| 291 | dst_release(ep->dst); | 291 | dst_release(ep->dst); |
| 292 | l2t_release(L2DATA(ep->com.tdev), ep->l2t); | 292 | l2t_release(L2DATA(ep->com.tdev), ep->l2t); |
| @@ -297,7 +297,7 @@ void __free_ep(struct kref *kref) | |||
| 297 | static void release_ep_resources(struct iwch_ep *ep) | 297 | static void release_ep_resources(struct iwch_ep *ep) |
| 298 | { | 298 | { |
| 299 | PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid); | 299 | PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid); |
| 300 | ep->com.flags |= RELEASE_RESOURCES; | 300 | set_bit(RELEASE_RESOURCES, &ep->com.flags); |
| 301 | put_ep(&ep->com); | 301 | put_ep(&ep->com); |
| 302 | } | 302 | } |
| 303 | 303 | ||
| @@ -786,10 +786,12 @@ static void connect_request_upcall(struct iwch_ep *ep) | |||
| 786 | event.private_data_len = ep->plen; | 786 | event.private_data_len = ep->plen; |
| 787 | event.private_data = ep->mpa_pkt + sizeof(struct mpa_message); | 787 | event.private_data = ep->mpa_pkt + sizeof(struct mpa_message); |
| 788 | event.provider_data = ep; | 788 | event.provider_data = ep; |
| 789 | if (state_read(&ep->parent_ep->com) != DEAD) | 789 | if (state_read(&ep->parent_ep->com) != DEAD) { |
| 790 | get_ep(&ep->com); | ||
| 790 | ep->parent_ep->com.cm_id->event_handler( | 791 | ep->parent_ep->com.cm_id->event_handler( |
| 791 | ep->parent_ep->com.cm_id, | 792 | ep->parent_ep->com.cm_id, |
| 792 | &event); | 793 | &event); |
| 794 | } | ||
| 793 | put_ep(&ep->parent_ep->com); | 795 | put_ep(&ep->parent_ep->com); |
| 794 | ep->parent_ep = NULL; | 796 | ep->parent_ep = NULL; |
| 795 | } | 797 | } |
| @@ -1156,8 +1158,7 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1156 | * We get 2 abort replies from the HW. The first one must | 1158 | * We get 2 abort replies from the HW. The first one must |
| 1157 | * be ignored except for scribbling that we need one more. | 1159 | * be ignored except for scribbling that we need one more. |
| 1158 | */ | 1160 | */ |
| 1159 | if (!(ep->com.flags & ABORT_REQ_IN_PROGRESS)) { | 1161 | if (!test_and_set_bit(ABORT_REQ_IN_PROGRESS, &ep->com.flags)) { |
| 1160 | ep->com.flags |= ABORT_REQ_IN_PROGRESS; | ||
| 1161 | return CPL_RET_BUF_DONE; | 1162 | return CPL_RET_BUF_DONE; |
| 1162 | } | 1163 | } |
| 1163 | 1164 | ||
| @@ -1480,7 +1481,6 @@ static int peer_close(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1480 | * rejects the CR. | 1481 | * rejects the CR. |
| 1481 | */ | 1482 | */ |
| 1482 | __state_set(&ep->com, CLOSING); | 1483 | __state_set(&ep->com, CLOSING); |
| 1483 | get_ep(&ep->com); | ||
| 1484 | break; | 1484 | break; |
| 1485 | case MPA_REP_SENT: | 1485 | case MPA_REP_SENT: |
| 1486 | __state_set(&ep->com, CLOSING); | 1486 | __state_set(&ep->com, CLOSING); |
| @@ -1561,8 +1561,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1561 | * We get 2 peer aborts from the HW. The first one must | 1561 | * We get 2 peer aborts from the HW. The first one must |
| 1562 | * be ignored except for scribbling that we need one more. | 1562 | * be ignored except for scribbling that we need one more. |
| 1563 | */ | 1563 | */ |
| 1564 | if (!(ep->com.flags & PEER_ABORT_IN_PROGRESS)) { | 1564 | if (!test_and_set_bit(PEER_ABORT_IN_PROGRESS, &ep->com.flags)) { |
| 1565 | ep->com.flags |= PEER_ABORT_IN_PROGRESS; | ||
| 1566 | return CPL_RET_BUF_DONE; | 1565 | return CPL_RET_BUF_DONE; |
| 1567 | } | 1566 | } |
| 1568 | 1567 | ||
| @@ -1591,7 +1590,6 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1591 | * the reference on it until the ULP accepts or | 1590 | * the reference on it until the ULP accepts or |
| 1592 | * rejects the CR. | 1591 | * rejects the CR. |
| 1593 | */ | 1592 | */ |
| 1594 | get_ep(&ep->com); | ||
| 1595 | break; | 1593 | break; |
| 1596 | case MORIBUND: | 1594 | case MORIBUND: |
| 1597 | case CLOSING: | 1595 | case CLOSING: |
| @@ -1797,6 +1795,7 @@ int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) | |||
| 1797 | err = send_mpa_reject(ep, pdata, pdata_len); | 1795 | err = send_mpa_reject(ep, pdata, pdata_len); |
| 1798 | err = iwch_ep_disconnect(ep, 0, GFP_KERNEL); | 1796 | err = iwch_ep_disconnect(ep, 0, GFP_KERNEL); |
| 1799 | } | 1797 | } |
| 1798 | put_ep(&ep->com); | ||
| 1800 | return 0; | 1799 | return 0; |
| 1801 | } | 1800 | } |
| 1802 | 1801 | ||
| @@ -1810,8 +1809,10 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
| 1810 | struct iwch_qp *qp = get_qhp(h, conn_param->qpn); | 1809 | struct iwch_qp *qp = get_qhp(h, conn_param->qpn); |
| 1811 | 1810 | ||
| 1812 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 1811 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
| 1813 | if (state_read(&ep->com) == DEAD) | 1812 | if (state_read(&ep->com) == DEAD) { |
| 1814 | return -ECONNRESET; | 1813 | err = -ECONNRESET; |
| 1814 | goto err; | ||
| 1815 | } | ||
| 1815 | 1816 | ||
| 1816 | BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD); | 1817 | BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD); |
| 1817 | BUG_ON(!qp); | 1818 | BUG_ON(!qp); |
| @@ -1819,7 +1820,8 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
| 1819 | if ((conn_param->ord > qp->rhp->attr.max_rdma_read_qp_depth) || | 1820 | if ((conn_param->ord > qp->rhp->attr.max_rdma_read_qp_depth) || |
| 1820 | (conn_param->ird > qp->rhp->attr.max_rdma_reads_per_qp)) { | 1821 | (conn_param->ird > qp->rhp->attr.max_rdma_reads_per_qp)) { |
| 1821 | abort_connection(ep, NULL, GFP_KERNEL); | 1822 | abort_connection(ep, NULL, GFP_KERNEL); |
| 1822 | return -EINVAL; | 1823 | err = -EINVAL; |
| 1824 | goto err; | ||
| 1823 | } | 1825 | } |
| 1824 | 1826 | ||
| 1825 | cm_id->add_ref(cm_id); | 1827 | cm_id->add_ref(cm_id); |
| @@ -1836,8 +1838,6 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
| 1836 | 1838 | ||
| 1837 | PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord); | 1839 | PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord); |
| 1838 | 1840 | ||
| 1839 | get_ep(&ep->com); | ||
| 1840 | |||
| 1841 | /* bind QP to EP and move to RTS */ | 1841 | /* bind QP to EP and move to RTS */ |
| 1842 | attrs.mpa_attr = ep->mpa_attr; | 1842 | attrs.mpa_attr = ep->mpa_attr; |
| 1843 | attrs.max_ird = ep->ird; | 1843 | attrs.max_ird = ep->ird; |
| @@ -1855,30 +1855,31 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
| 1855 | err = iwch_modify_qp(ep->com.qp->rhp, | 1855 | err = iwch_modify_qp(ep->com.qp->rhp, |
| 1856 | ep->com.qp, mask, &attrs, 1); | 1856 | ep->com.qp, mask, &attrs, 1); |
| 1857 | if (err) | 1857 | if (err) |
| 1858 | goto err; | 1858 | goto err1; |
| 1859 | 1859 | ||
| 1860 | /* if needed, wait for wr_ack */ | 1860 | /* if needed, wait for wr_ack */ |
| 1861 | if (iwch_rqes_posted(qp)) { | 1861 | if (iwch_rqes_posted(qp)) { |
| 1862 | wait_event(ep->com.waitq, ep->com.rpl_done); | 1862 | wait_event(ep->com.waitq, ep->com.rpl_done); |
| 1863 | err = ep->com.rpl_err; | 1863 | err = ep->com.rpl_err; |
| 1864 | if (err) | 1864 | if (err) |
| 1865 | goto err; | 1865 | goto err1; |
| 1866 | } | 1866 | } |
| 1867 | 1867 | ||
| 1868 | err = send_mpa_reply(ep, conn_param->private_data, | 1868 | err = send_mpa_reply(ep, conn_param->private_data, |
| 1869 | conn_param->private_data_len); | 1869 | conn_param->private_data_len); |
| 1870 | if (err) | 1870 | if (err) |
| 1871 | goto err; | 1871 | goto err1; |
| 1872 | 1872 | ||
| 1873 | 1873 | ||
| 1874 | state_set(&ep->com, FPDU_MODE); | 1874 | state_set(&ep->com, FPDU_MODE); |
| 1875 | established_upcall(ep); | 1875 | established_upcall(ep); |
| 1876 | put_ep(&ep->com); | 1876 | put_ep(&ep->com); |
| 1877 | return 0; | 1877 | return 0; |
| 1878 | err: | 1878 | err1: |
| 1879 | ep->com.cm_id = NULL; | 1879 | ep->com.cm_id = NULL; |
| 1880 | ep->com.qp = NULL; | 1880 | ep->com.qp = NULL; |
| 1881 | cm_id->rem_ref(cm_id); | 1881 | cm_id->rem_ref(cm_id); |
| 1882 | err: | ||
| 1882 | put_ep(&ep->com); | 1883 | put_ep(&ep->com); |
| 1883 | return err; | 1884 | return err; |
| 1884 | } | 1885 | } |
| @@ -2097,14 +2098,17 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) | |||
| 2097 | ep->com.state = CLOSING; | 2098 | ep->com.state = CLOSING; |
| 2098 | start_ep_timer(ep); | 2099 | start_ep_timer(ep); |
| 2099 | } | 2100 | } |
| 2101 | set_bit(CLOSE_SENT, &ep->com.flags); | ||
| 2100 | break; | 2102 | break; |
| 2101 | case CLOSING: | 2103 | case CLOSING: |
| 2102 | close = 1; | 2104 | if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) { |
| 2103 | if (abrupt) { | 2105 | close = 1; |
| 2104 | stop_ep_timer(ep); | 2106 | if (abrupt) { |
| 2105 | ep->com.state = ABORTING; | 2107 | stop_ep_timer(ep); |
| 2106 | } else | 2108 | ep->com.state = ABORTING; |
| 2107 | ep->com.state = MORIBUND; | 2109 | } else |
| 2110 | ep->com.state = MORIBUND; | ||
| 2111 | } | ||
| 2108 | break; | 2112 | break; |
| 2109 | case MORIBUND: | 2113 | case MORIBUND: |
| 2110 | case ABORTING: | 2114 | case ABORTING: |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h index 43c0aea7ead..b9efadfffb4 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.h +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h | |||
| @@ -145,9 +145,10 @@ enum iwch_ep_state { | |||
| 145 | }; | 145 | }; |
| 146 | 146 | ||
| 147 | enum iwch_ep_flags { | 147 | enum iwch_ep_flags { |
| 148 | PEER_ABORT_IN_PROGRESS = (1 << 0), | 148 | PEER_ABORT_IN_PROGRESS = 0, |
| 149 | ABORT_REQ_IN_PROGRESS = (1 << 1), | 149 | ABORT_REQ_IN_PROGRESS = 1, |
| 150 | RELEASE_RESOURCES = (1 << 2), | 150 | RELEASE_RESOURCES = 2, |
| 151 | CLOSE_SENT = 3, | ||
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 153 | struct iwch_ep_common { | 154 | struct iwch_ep_common { |
| @@ -162,7 +163,7 @@ struct iwch_ep_common { | |||
| 162 | wait_queue_head_t waitq; | 163 | wait_queue_head_t waitq; |
| 163 | int rpl_done; | 164 | int rpl_done; |
| 164 | int rpl_err; | 165 | int rpl_err; |
| 165 | u32 flags; | 166 | unsigned long flags; |
| 166 | }; | 167 | }; |
| 167 | 168 | ||
| 168 | struct iwch_listen_ep { | 169 | struct iwch_listen_ep { |
