diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 87 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/qp.c | 90 |
3 files changed, 88 insertions, 93 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 6819ac4cbcbb..9b5c3e38e452 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -219,12 +219,11 @@ static void set_emss(struct c4iw_ep *ep, u16 opt) | |||
219 | 219 | ||
220 | static enum c4iw_ep_state state_read(struct c4iw_ep_common *epc) | 220 | static enum c4iw_ep_state state_read(struct c4iw_ep_common *epc) |
221 | { | 221 | { |
222 | unsigned long flags; | ||
223 | enum c4iw_ep_state state; | 222 | enum c4iw_ep_state state; |
224 | 223 | ||
225 | spin_lock_irqsave(&epc->lock, flags); | 224 | mutex_lock(&epc->mutex); |
226 | state = epc->state; | 225 | state = epc->state; |
227 | spin_unlock_irqrestore(&epc->lock, flags); | 226 | mutex_unlock(&epc->mutex); |
228 | return state; | 227 | return state; |
229 | } | 228 | } |
230 | 229 | ||
@@ -235,12 +234,10 @@ static void __state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new) | |||
235 | 234 | ||
236 | static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new) | 235 | static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new) |
237 | { | 236 | { |
238 | unsigned long flags; | 237 | mutex_lock(&epc->mutex); |
239 | |||
240 | spin_lock_irqsave(&epc->lock, flags); | ||
241 | PDBG("%s - %s -> %s\n", __func__, states[epc->state], states[new]); | 238 | PDBG("%s - %s -> %s\n", __func__, states[epc->state], states[new]); |
242 | __state_set(epc, new); | 239 | __state_set(epc, new); |
243 | spin_unlock_irqrestore(&epc->lock, flags); | 240 | mutex_unlock(&epc->mutex); |
244 | return; | 241 | return; |
245 | } | 242 | } |
246 | 243 | ||
@@ -251,7 +248,7 @@ static void *alloc_ep(int size, gfp_t gfp) | |||
251 | epc = kzalloc(size, gfp); | 248 | epc = kzalloc(size, gfp); |
252 | if (epc) { | 249 | if (epc) { |
253 | kref_init(&epc->kref); | 250 | kref_init(&epc->kref); |
254 | spin_lock_init(&epc->lock); | 251 | mutex_init(&epc->mutex); |
255 | c4iw_init_wr_wait(&epc->wr_wait); | 252 | c4iw_init_wr_wait(&epc->wr_wait); |
256 | } | 253 | } |
257 | PDBG("%s alloc ep %p\n", __func__, epc); | 254 | PDBG("%s alloc ep %p\n", __func__, epc); |
@@ -1131,7 +1128,6 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1131 | { | 1128 | { |
1132 | struct c4iw_ep *ep; | 1129 | struct c4iw_ep *ep; |
1133 | struct cpl_abort_rpl_rss *rpl = cplhdr(skb); | 1130 | struct cpl_abort_rpl_rss *rpl = cplhdr(skb); |
1134 | unsigned long flags; | ||
1135 | int release = 0; | 1131 | int release = 0; |
1136 | unsigned int tid = GET_TID(rpl); | 1132 | unsigned int tid = GET_TID(rpl); |
1137 | struct tid_info *t = dev->rdev.lldi.tids; | 1133 | struct tid_info *t = dev->rdev.lldi.tids; |
@@ -1139,7 +1135,7 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1139 | ep = lookup_tid(t, tid); | 1135 | ep = lookup_tid(t, tid); |
1140 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 1136 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
1141 | BUG_ON(!ep); | 1137 | BUG_ON(!ep); |
1142 | spin_lock_irqsave(&ep->com.lock, flags); | 1138 | mutex_lock(&ep->com.mutex); |
1143 | switch (ep->com.state) { | 1139 | switch (ep->com.state) { |
1144 | case ABORTING: | 1140 | case ABORTING: |
1145 | __state_set(&ep->com, DEAD); | 1141 | __state_set(&ep->com, DEAD); |
@@ -1150,7 +1146,7 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1150 | __func__, ep, ep->com.state); | 1146 | __func__, ep, ep->com.state); |
1151 | break; | 1147 | break; |
1152 | } | 1148 | } |
1153 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1149 | mutex_unlock(&ep->com.mutex); |
1154 | 1150 | ||
1155 | if (release) | 1151 | if (release) |
1156 | release_ep_resources(ep); | 1152 | release_ep_resources(ep); |
@@ -1478,7 +1474,6 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1478 | struct cpl_peer_close *hdr = cplhdr(skb); | 1474 | struct cpl_peer_close *hdr = cplhdr(skb); |
1479 | struct c4iw_ep *ep; | 1475 | struct c4iw_ep *ep; |
1480 | struct c4iw_qp_attributes attrs; | 1476 | struct c4iw_qp_attributes attrs; |
1481 | unsigned long flags; | ||
1482 | int disconnect = 1; | 1477 | int disconnect = 1; |
1483 | int release = 0; | 1478 | int release = 0; |
1484 | int closing = 0; | 1479 | int closing = 0; |
@@ -1489,7 +1484,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1489 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | 1484 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); |
1490 | dst_confirm(ep->dst); | 1485 | dst_confirm(ep->dst); |
1491 | 1486 | ||
1492 | spin_lock_irqsave(&ep->com.lock, flags); | 1487 | mutex_lock(&ep->com.mutex); |
1493 | switch (ep->com.state) { | 1488 | switch (ep->com.state) { |
1494 | case MPA_REQ_WAIT: | 1489 | case MPA_REQ_WAIT: |
1495 | __state_set(&ep->com, CLOSING); | 1490 | __state_set(&ep->com, CLOSING); |
@@ -1550,7 +1545,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1550 | default: | 1545 | default: |
1551 | BUG_ON(1); | 1546 | BUG_ON(1); |
1552 | } | 1547 | } |
1553 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1548 | mutex_unlock(&ep->com.mutex); |
1554 | if (closing) { | 1549 | if (closing) { |
1555 | attrs.next_state = C4IW_QP_STATE_CLOSING; | 1550 | attrs.next_state = C4IW_QP_STATE_CLOSING; |
1556 | c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, | 1551 | c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, |
@@ -1581,7 +1576,6 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1581 | struct c4iw_qp_attributes attrs; | 1576 | struct c4iw_qp_attributes attrs; |
1582 | int ret; | 1577 | int ret; |
1583 | int release = 0; | 1578 | int release = 0; |
1584 | unsigned long flags; | ||
1585 | struct tid_info *t = dev->rdev.lldi.tids; | 1579 | struct tid_info *t = dev->rdev.lldi.tids; |
1586 | unsigned int tid = GET_TID(req); | 1580 | unsigned int tid = GET_TID(req); |
1587 | 1581 | ||
@@ -1591,9 +1585,17 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1591 | ep->hwtid); | 1585 | ep->hwtid); |
1592 | return 0; | 1586 | return 0; |
1593 | } | 1587 | } |
1594 | spin_lock_irqsave(&ep->com.lock, flags); | ||
1595 | PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, | 1588 | PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, |
1596 | ep->com.state); | 1589 | ep->com.state); |
1590 | |||
1591 | /* | ||
1592 | * Wake up any threads in rdma_init() or rdma_fini(). | ||
1593 | */ | ||
1594 | ep->com.wr_wait.done = 1; | ||
1595 | ep->com.wr_wait.ret = -ECONNRESET; | ||
1596 | wake_up(&ep->com.wr_wait.wait); | ||
1597 | |||
1598 | mutex_lock(&ep->com.mutex); | ||
1597 | switch (ep->com.state) { | 1599 | switch (ep->com.state) { |
1598 | case CONNECTING: | 1600 | case CONNECTING: |
1599 | break; | 1601 | break; |
@@ -1605,23 +1607,8 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1605 | connect_reply_upcall(ep, -ECONNRESET); | 1607 | connect_reply_upcall(ep, -ECONNRESET); |
1606 | break; | 1608 | break; |
1607 | case MPA_REP_SENT: | 1609 | case MPA_REP_SENT: |
1608 | ep->com.wr_wait.done = 1; | ||
1609 | ep->com.wr_wait.ret = -ECONNRESET; | ||
1610 | PDBG("waking up ep %p\n", ep); | ||
1611 | wake_up(&ep->com.wr_wait.wait); | ||
1612 | break; | 1610 | break; |
1613 | case MPA_REQ_RCVD: | 1611 | case MPA_REQ_RCVD: |
1614 | |||
1615 | /* | ||
1616 | * We're gonna mark this puppy DEAD, but keep | ||
1617 | * the reference on it until the ULP accepts or | ||
1618 | * rejects the CR. Also wake up anyone waiting | ||
1619 | * in rdma connection migration (see c4iw_accept_cr()). | ||
1620 | */ | ||
1621 | ep->com.wr_wait.done = 1; | ||
1622 | ep->com.wr_wait.ret = -ECONNRESET; | ||
1623 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); | ||
1624 | wake_up(&ep->com.wr_wait.wait); | ||
1625 | break; | 1612 | break; |
1626 | case MORIBUND: | 1613 | case MORIBUND: |
1627 | case CLOSING: | 1614 | case CLOSING: |
@@ -1644,7 +1631,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1644 | break; | 1631 | break; |
1645 | case DEAD: | 1632 | case DEAD: |
1646 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); | 1633 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); |
1647 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1634 | mutex_unlock(&ep->com.mutex); |
1648 | return 0; | 1635 | return 0; |
1649 | default: | 1636 | default: |
1650 | BUG_ON(1); | 1637 | BUG_ON(1); |
@@ -1655,7 +1642,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1655 | __state_set(&ep->com, DEAD); | 1642 | __state_set(&ep->com, DEAD); |
1656 | release = 1; | 1643 | release = 1; |
1657 | } | 1644 | } |
1658 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1645 | mutex_unlock(&ep->com.mutex); |
1659 | 1646 | ||
1660 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); | 1647 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); |
1661 | if (!rpl_skb) { | 1648 | if (!rpl_skb) { |
@@ -1681,7 +1668,6 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1681 | struct c4iw_ep *ep; | 1668 | struct c4iw_ep *ep; |
1682 | struct c4iw_qp_attributes attrs; | 1669 | struct c4iw_qp_attributes attrs; |
1683 | struct cpl_close_con_rpl *rpl = cplhdr(skb); | 1670 | struct cpl_close_con_rpl *rpl = cplhdr(skb); |
1684 | unsigned long flags; | ||
1685 | int release = 0; | 1671 | int release = 0; |
1686 | struct tid_info *t = dev->rdev.lldi.tids; | 1672 | struct tid_info *t = dev->rdev.lldi.tids; |
1687 | unsigned int tid = GET_TID(rpl); | 1673 | unsigned int tid = GET_TID(rpl); |
@@ -1692,7 +1678,7 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1692 | BUG_ON(!ep); | 1678 | BUG_ON(!ep); |
1693 | 1679 | ||
1694 | /* The cm_id may be null if we failed to connect */ | 1680 | /* The cm_id may be null if we failed to connect */ |
1695 | spin_lock_irqsave(&ep->com.lock, flags); | 1681 | mutex_lock(&ep->com.mutex); |
1696 | switch (ep->com.state) { | 1682 | switch (ep->com.state) { |
1697 | case CLOSING: | 1683 | case CLOSING: |
1698 | __state_set(&ep->com, MORIBUND); | 1684 | __state_set(&ep->com, MORIBUND); |
@@ -1717,7 +1703,7 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1717 | BUG_ON(1); | 1703 | BUG_ON(1); |
1718 | break; | 1704 | break; |
1719 | } | 1705 | } |
1720 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1706 | mutex_unlock(&ep->com.mutex); |
1721 | if (release) | 1707 | if (release) |
1722 | release_ep_resources(ep); | 1708 | release_ep_resources(ep); |
1723 | return 0; | 1709 | return 0; |
@@ -2093,12 +2079,11 @@ done: | |||
2093 | int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) | 2079 | int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) |
2094 | { | 2080 | { |
2095 | int ret = 0; | 2081 | int ret = 0; |
2096 | unsigned long flags; | ||
2097 | int close = 0; | 2082 | int close = 0; |
2098 | int fatal = 0; | 2083 | int fatal = 0; |
2099 | struct c4iw_rdev *rdev; | 2084 | struct c4iw_rdev *rdev; |
2100 | 2085 | ||
2101 | spin_lock_irqsave(&ep->com.lock, flags); | 2086 | mutex_lock(&ep->com.mutex); |
2102 | 2087 | ||
2103 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, | 2088 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, |
2104 | states[ep->com.state], abrupt); | 2089 | states[ep->com.state], abrupt); |
@@ -2145,7 +2130,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) | |||
2145 | break; | 2130 | break; |
2146 | } | 2131 | } |
2147 | 2132 | ||
2148 | spin_unlock_irqrestore(&ep->com.lock, flags); | 2133 | mutex_unlock(&ep->com.mutex); |
2149 | if (close) { | 2134 | if (close) { |
2150 | if (abrupt) | 2135 | if (abrupt) |
2151 | ret = abort_connection(ep, NULL, gfp); | 2136 | ret = abort_connection(ep, NULL, gfp); |
@@ -2159,6 +2144,13 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) | |||
2159 | return ret; | 2144 | return ret; |
2160 | } | 2145 | } |
2161 | 2146 | ||
2147 | static int async_event(struct c4iw_dev *dev, struct sk_buff *skb) | ||
2148 | { | ||
2149 | struct cpl_fw6_msg *rpl = cplhdr(skb); | ||
2150 | c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]); | ||
2151 | return 0; | ||
2152 | } | ||
2153 | |||
2162 | /* | 2154 | /* |
2163 | * These are the real handlers that are called from a | 2155 | * These are the real handlers that are called from a |
2164 | * work queue. | 2156 | * work queue. |
@@ -2177,7 +2169,8 @@ static c4iw_handler_func work_handlers[NUM_CPL_CMDS] = { | |||
2177 | [CPL_ABORT_REQ_RSS] = peer_abort, | 2169 | [CPL_ABORT_REQ_RSS] = peer_abort, |
2178 | [CPL_CLOSE_CON_RPL] = close_con_rpl, | 2170 | [CPL_CLOSE_CON_RPL] = close_con_rpl, |
2179 | [CPL_RDMA_TERMINATE] = terminate, | 2171 | [CPL_RDMA_TERMINATE] = terminate, |
2180 | [CPL_FW4_ACK] = fw4_ack | 2172 | [CPL_FW4_ACK] = fw4_ack, |
2173 | [CPL_FW6_MSG] = async_event | ||
2181 | }; | 2174 | }; |
2182 | 2175 | ||
2183 | static void process_timeout(struct c4iw_ep *ep) | 2176 | static void process_timeout(struct c4iw_ep *ep) |
@@ -2185,7 +2178,7 @@ static void process_timeout(struct c4iw_ep *ep) | |||
2185 | struct c4iw_qp_attributes attrs; | 2178 | struct c4iw_qp_attributes attrs; |
2186 | int abort = 1; | 2179 | int abort = 1; |
2187 | 2180 | ||
2188 | spin_lock_irq(&ep->com.lock); | 2181 | mutex_lock(&ep->com.mutex); |
2189 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, | 2182 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, |
2190 | ep->com.state); | 2183 | ep->com.state); |
2191 | switch (ep->com.state) { | 2184 | switch (ep->com.state) { |
@@ -2212,7 +2205,7 @@ static void process_timeout(struct c4iw_ep *ep) | |||
2212 | WARN_ON(1); | 2205 | WARN_ON(1); |
2213 | abort = 0; | 2206 | abort = 0; |
2214 | } | 2207 | } |
2215 | spin_unlock_irq(&ep->com.lock); | 2208 | mutex_unlock(&ep->com.mutex); |
2216 | if (abort) | 2209 | if (abort) |
2217 | abort_connection(ep, NULL, GFP_KERNEL); | 2210 | abort_connection(ep, NULL, GFP_KERNEL); |
2218 | c4iw_put_ep(&ep->com); | 2211 | c4iw_put_ep(&ep->com); |
@@ -2296,6 +2289,7 @@ static int set_tcb_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
2296 | printk(KERN_ERR MOD "Unexpected SET_TCB_RPL status %u " | 2289 | printk(KERN_ERR MOD "Unexpected SET_TCB_RPL status %u " |
2297 | "for tid %u\n", rpl->status, GET_TID(rpl)); | 2290 | "for tid %u\n", rpl->status, GET_TID(rpl)); |
2298 | } | 2291 | } |
2292 | kfree_skb(skb); | ||
2299 | return 0; | 2293 | return 0; |
2300 | } | 2294 | } |
2301 | 2295 | ||
@@ -2313,17 +2307,22 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) | |||
2313 | wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1]; | 2307 | wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1]; |
2314 | PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret); | 2308 | PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret); |
2315 | if (wr_waitp) { | 2309 | if (wr_waitp) { |
2316 | wr_waitp->ret = ret; | 2310 | if (ret) |
2311 | wr_waitp->ret = -ret; | ||
2312 | else | ||
2313 | wr_waitp->ret = 0; | ||
2317 | wr_waitp->done = 1; | 2314 | wr_waitp->done = 1; |
2318 | wake_up(&wr_waitp->wait); | 2315 | wake_up(&wr_waitp->wait); |
2319 | } | 2316 | } |
2317 | kfree_skb(skb); | ||
2320 | break; | 2318 | break; |
2321 | case 2: | 2319 | case 2: |
2322 | c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]); | 2320 | sched(dev, skb); |
2323 | break; | 2321 | break; |
2324 | default: | 2322 | default: |
2325 | printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__, | 2323 | printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__, |
2326 | rpl->type); | 2324 | rpl->type); |
2325 | kfree_skb(skb); | ||
2327 | break; | 2326 | break; |
2328 | } | 2327 | } |
2329 | return 0; | 2328 | return 0; |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 1c269223945e..16032cdb4337 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
47 | #include <linux/io.h> | 47 | #include <linux/io.h> |
48 | #include <linux/kfifo.h> | 48 | #include <linux/kfifo.h> |
49 | #include <linux/mutex.h> | ||
49 | 50 | ||
50 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
51 | 52 | ||
@@ -353,6 +354,7 @@ struct c4iw_qp { | |||
353 | struct c4iw_qp_attributes attr; | 354 | struct c4iw_qp_attributes attr; |
354 | struct t4_wq wq; | 355 | struct t4_wq wq; |
355 | spinlock_t lock; | 356 | spinlock_t lock; |
357 | struct mutex mutex; | ||
356 | atomic_t refcnt; | 358 | atomic_t refcnt; |
357 | wait_queue_head_t wait; | 359 | wait_queue_head_t wait; |
358 | struct timer_list timer; | 360 | struct timer_list timer; |
@@ -605,7 +607,7 @@ struct c4iw_ep_common { | |||
605 | struct c4iw_dev *dev; | 607 | struct c4iw_dev *dev; |
606 | enum c4iw_ep_state state; | 608 | enum c4iw_ep_state state; |
607 | struct kref kref; | 609 | struct kref kref; |
608 | spinlock_t lock; | 610 | struct mutex mutex; |
609 | struct sockaddr_in local_addr; | 611 | struct sockaddr_in local_addr; |
610 | struct sockaddr_in remote_addr; | 612 | struct sockaddr_in remote_addr; |
611 | struct c4iw_wr_wait wr_wait; | 613 | struct c4iw_wr_wait wr_wait; |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 7e45f7334282..76a286f88edd 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
@@ -35,6 +35,14 @@ static int ocqp_support; | |||
35 | module_param(ocqp_support, int, 0644); | 35 | module_param(ocqp_support, int, 0644); |
36 | MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=0)"); | 36 | MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=0)"); |
37 | 37 | ||
38 | static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) | ||
39 | { | ||
40 | unsigned long flag; | ||
41 | spin_lock_irqsave(&qhp->lock, flag); | ||
42 | qhp->attr.state = state; | ||
43 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
44 | } | ||
45 | |||
38 | static void dealloc_oc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) | 46 | static void dealloc_oc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) |
39 | { | 47 | { |
40 | c4iw_ocqp_pool_free(rdev, sq->dma_addr, sq->memsize); | 48 | c4iw_ocqp_pool_free(rdev, sq->dma_addr, sq->memsize); |
@@ -949,46 +957,38 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe, | |||
949 | * Assumes qhp lock is held. | 957 | * Assumes qhp lock is held. |
950 | */ | 958 | */ |
951 | static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, | 959 | static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, |
952 | struct c4iw_cq *schp, unsigned long *flag) | 960 | struct c4iw_cq *schp) |
953 | { | 961 | { |
954 | int count; | 962 | int count; |
955 | int flushed; | 963 | int flushed; |
964 | unsigned long flag; | ||
956 | 965 | ||
957 | PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp); | 966 | PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp); |
958 | /* take a ref on the qhp since we must release the lock */ | ||
959 | atomic_inc(&qhp->refcnt); | ||
960 | spin_unlock_irqrestore(&qhp->lock, *flag); | ||
961 | 967 | ||
962 | /* locking hierarchy: cq lock first, then qp lock. */ | 968 | /* locking hierarchy: cq lock first, then qp lock. */ |
963 | spin_lock_irqsave(&rchp->lock, *flag); | 969 | spin_lock_irqsave(&rchp->lock, flag); |
964 | spin_lock(&qhp->lock); | 970 | spin_lock(&qhp->lock); |
965 | c4iw_flush_hw_cq(&rchp->cq); | 971 | c4iw_flush_hw_cq(&rchp->cq); |
966 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); | 972 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); |
967 | flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); | 973 | flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); |
968 | spin_unlock(&qhp->lock); | 974 | spin_unlock(&qhp->lock); |
969 | spin_unlock_irqrestore(&rchp->lock, *flag); | 975 | spin_unlock_irqrestore(&rchp->lock, flag); |
970 | if (flushed) | 976 | if (flushed) |
971 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | 977 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); |
972 | 978 | ||
973 | /* locking hierarchy: cq lock first, then qp lock. */ | 979 | /* locking hierarchy: cq lock first, then qp lock. */ |
974 | spin_lock_irqsave(&schp->lock, *flag); | 980 | spin_lock_irqsave(&schp->lock, flag); |
975 | spin_lock(&qhp->lock); | 981 | spin_lock(&qhp->lock); |
976 | c4iw_flush_hw_cq(&schp->cq); | 982 | c4iw_flush_hw_cq(&schp->cq); |
977 | c4iw_count_scqes(&schp->cq, &qhp->wq, &count); | 983 | c4iw_count_scqes(&schp->cq, &qhp->wq, &count); |
978 | flushed = c4iw_flush_sq(&qhp->wq, &schp->cq, count); | 984 | flushed = c4iw_flush_sq(&qhp->wq, &schp->cq, count); |
979 | spin_unlock(&qhp->lock); | 985 | spin_unlock(&qhp->lock); |
980 | spin_unlock_irqrestore(&schp->lock, *flag); | 986 | spin_unlock_irqrestore(&schp->lock, flag); |
981 | if (flushed) | 987 | if (flushed) |
982 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | 988 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); |
983 | |||
984 | /* deref */ | ||
985 | if (atomic_dec_and_test(&qhp->refcnt)) | ||
986 | wake_up(&qhp->wait); | ||
987 | |||
988 | spin_lock_irqsave(&qhp->lock, *flag); | ||
989 | } | 989 | } |
990 | 990 | ||
991 | static void flush_qp(struct c4iw_qp *qhp, unsigned long *flag) | 991 | static void flush_qp(struct c4iw_qp *qhp) |
992 | { | 992 | { |
993 | struct c4iw_cq *rchp, *schp; | 993 | struct c4iw_cq *rchp, *schp; |
994 | 994 | ||
@@ -1002,7 +1002,7 @@ static void flush_qp(struct c4iw_qp *qhp, unsigned long *flag) | |||
1002 | t4_set_cq_in_error(&schp->cq); | 1002 | t4_set_cq_in_error(&schp->cq); |
1003 | return; | 1003 | return; |
1004 | } | 1004 | } |
1005 | __flush_qp(qhp, rchp, schp, flag); | 1005 | __flush_qp(qhp, rchp, schp); |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | 1008 | static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, |
@@ -1010,7 +1010,6 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1010 | { | 1010 | { |
1011 | struct fw_ri_wr *wqe; | 1011 | struct fw_ri_wr *wqe; |
1012 | int ret; | 1012 | int ret; |
1013 | struct c4iw_wr_wait wr_wait; | ||
1014 | struct sk_buff *skb; | 1013 | struct sk_buff *skb; |
1015 | 1014 | ||
1016 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, | 1015 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, |
@@ -1029,15 +1028,15 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1029 | wqe->flowid_len16 = cpu_to_be32( | 1028 | wqe->flowid_len16 = cpu_to_be32( |
1030 | FW_WR_FLOWID(ep->hwtid) | | 1029 | FW_WR_FLOWID(ep->hwtid) | |
1031 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); | 1030 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); |
1032 | wqe->cookie = (unsigned long) &wr_wait; | 1031 | wqe->cookie = (unsigned long) &ep->com.wr_wait; |
1033 | 1032 | ||
1034 | wqe->u.fini.type = FW_RI_TYPE_FINI; | 1033 | wqe->u.fini.type = FW_RI_TYPE_FINI; |
1035 | c4iw_init_wr_wait(&wr_wait); | 1034 | c4iw_init_wr_wait(&ep->com.wr_wait); |
1036 | ret = c4iw_ofld_send(&rhp->rdev, skb); | 1035 | ret = c4iw_ofld_send(&rhp->rdev, skb); |
1037 | if (ret) | 1036 | if (ret) |
1038 | goto out; | 1037 | goto out; |
1039 | 1038 | ||
1040 | ret = c4iw_wait_for_reply(&rhp->rdev, &wr_wait, qhp->ep->hwtid, | 1039 | ret = c4iw_wait_for_reply(&rhp->rdev, &ep->com.wr_wait, qhp->ep->hwtid, |
1041 | qhp->wq.sq.qid, __func__); | 1040 | qhp->wq.sq.qid, __func__); |
1042 | out: | 1041 | out: |
1043 | PDBG("%s ret %d\n", __func__, ret); | 1042 | PDBG("%s ret %d\n", __func__, ret); |
@@ -1072,7 +1071,6 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
1072 | { | 1071 | { |
1073 | struct fw_ri_wr *wqe; | 1072 | struct fw_ri_wr *wqe; |
1074 | int ret; | 1073 | int ret; |
1075 | struct c4iw_wr_wait wr_wait; | ||
1076 | struct sk_buff *skb; | 1074 | struct sk_buff *skb; |
1077 | 1075 | ||
1078 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, | 1076 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, |
@@ -1092,7 +1090,7 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
1092 | FW_WR_FLOWID(qhp->ep->hwtid) | | 1090 | FW_WR_FLOWID(qhp->ep->hwtid) | |
1093 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); | 1091 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); |
1094 | 1092 | ||
1095 | wqe->cookie = (unsigned long) &wr_wait; | 1093 | wqe->cookie = (unsigned long) &qhp->ep->com.wr_wait; |
1096 | 1094 | ||
1097 | wqe->u.init.type = FW_RI_TYPE_INIT; | 1095 | wqe->u.init.type = FW_RI_TYPE_INIT; |
1098 | wqe->u.init.mpareqbit_p2ptype = | 1096 | wqe->u.init.mpareqbit_p2ptype = |
@@ -1129,13 +1127,13 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
1129 | if (qhp->attr.mpa_attr.initiator) | 1127 | if (qhp->attr.mpa_attr.initiator) |
1130 | build_rtr_msg(qhp->attr.mpa_attr.p2p_type, &wqe->u.init); | 1128 | build_rtr_msg(qhp->attr.mpa_attr.p2p_type, &wqe->u.init); |
1131 | 1129 | ||
1132 | c4iw_init_wr_wait(&wr_wait); | 1130 | c4iw_init_wr_wait(&qhp->ep->com.wr_wait); |
1133 | ret = c4iw_ofld_send(&rhp->rdev, skb); | 1131 | ret = c4iw_ofld_send(&rhp->rdev, skb); |
1134 | if (ret) | 1132 | if (ret) |
1135 | goto out; | 1133 | goto out; |
1136 | 1134 | ||
1137 | ret = c4iw_wait_for_reply(&rhp->rdev, &wr_wait, qhp->ep->hwtid, | 1135 | ret = c4iw_wait_for_reply(&rhp->rdev, &qhp->ep->com.wr_wait, |
1138 | qhp->wq.sq.qid, __func__); | 1136 | qhp->ep->hwtid, qhp->wq.sq.qid, __func__); |
1139 | out: | 1137 | out: |
1140 | PDBG("%s ret %d\n", __func__, ret); | 1138 | PDBG("%s ret %d\n", __func__, ret); |
1141 | return ret; | 1139 | return ret; |
@@ -1148,7 +1146,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1148 | { | 1146 | { |
1149 | int ret = 0; | 1147 | int ret = 0; |
1150 | struct c4iw_qp_attributes newattr = qhp->attr; | 1148 | struct c4iw_qp_attributes newattr = qhp->attr; |
1151 | unsigned long flag; | ||
1152 | int disconnect = 0; | 1149 | int disconnect = 0; |
1153 | int terminate = 0; | 1150 | int terminate = 0; |
1154 | int abort = 0; | 1151 | int abort = 0; |
@@ -1159,7 +1156,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1159 | qhp, qhp->wq.sq.qid, qhp->wq.rq.qid, qhp->ep, qhp->attr.state, | 1156 | qhp, qhp->wq.sq.qid, qhp->wq.rq.qid, qhp->ep, qhp->attr.state, |
1160 | (mask & C4IW_QP_ATTR_NEXT_STATE) ? attrs->next_state : -1); | 1157 | (mask & C4IW_QP_ATTR_NEXT_STATE) ? attrs->next_state : -1); |
1161 | 1158 | ||
1162 | spin_lock_irqsave(&qhp->lock, flag); | 1159 | mutex_lock(&qhp->mutex); |
1163 | 1160 | ||
1164 | /* Process attr changes if in IDLE */ | 1161 | /* Process attr changes if in IDLE */ |
1165 | if (mask & C4IW_QP_ATTR_VALID_MODIFY) { | 1162 | if (mask & C4IW_QP_ATTR_VALID_MODIFY) { |
@@ -1210,7 +1207,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1210 | qhp->attr.mpa_attr = attrs->mpa_attr; | 1207 | qhp->attr.mpa_attr = attrs->mpa_attr; |
1211 | qhp->attr.llp_stream_handle = attrs->llp_stream_handle; | 1208 | qhp->attr.llp_stream_handle = attrs->llp_stream_handle; |
1212 | qhp->ep = qhp->attr.llp_stream_handle; | 1209 | qhp->ep = qhp->attr.llp_stream_handle; |
1213 | qhp->attr.state = C4IW_QP_STATE_RTS; | 1210 | set_state(qhp, C4IW_QP_STATE_RTS); |
1214 | 1211 | ||
1215 | /* | 1212 | /* |
1216 | * Ref the endpoint here and deref when we | 1213 | * Ref the endpoint here and deref when we |
@@ -1219,15 +1216,13 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1219 | * transition. | 1216 | * transition. |
1220 | */ | 1217 | */ |
1221 | c4iw_get_ep(&qhp->ep->com); | 1218 | c4iw_get_ep(&qhp->ep->com); |
1222 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
1223 | ret = rdma_init(rhp, qhp); | 1219 | ret = rdma_init(rhp, qhp); |
1224 | spin_lock_irqsave(&qhp->lock, flag); | ||
1225 | if (ret) | 1220 | if (ret) |
1226 | goto err; | 1221 | goto err; |
1227 | break; | 1222 | break; |
1228 | case C4IW_QP_STATE_ERROR: | 1223 | case C4IW_QP_STATE_ERROR: |
1229 | qhp->attr.state = C4IW_QP_STATE_ERROR; | 1224 | set_state(qhp, C4IW_QP_STATE_ERROR); |
1230 | flush_qp(qhp, &flag); | 1225 | flush_qp(qhp); |
1231 | break; | 1226 | break; |
1232 | default: | 1227 | default: |
1233 | ret = -EINVAL; | 1228 | ret = -EINVAL; |
@@ -1238,39 +1233,38 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1238 | switch (attrs->next_state) { | 1233 | switch (attrs->next_state) { |
1239 | case C4IW_QP_STATE_CLOSING: | 1234 | case C4IW_QP_STATE_CLOSING: |
1240 | BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); | 1235 | BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); |
1241 | qhp->attr.state = C4IW_QP_STATE_CLOSING; | 1236 | set_state(qhp, C4IW_QP_STATE_CLOSING); |
1242 | ep = qhp->ep; | 1237 | ep = qhp->ep; |
1243 | if (!internal) { | 1238 | if (!internal) { |
1244 | abort = 0; | 1239 | abort = 0; |
1245 | disconnect = 1; | 1240 | disconnect = 1; |
1246 | c4iw_get_ep(&ep->com); | 1241 | c4iw_get_ep(&qhp->ep->com); |
1247 | } | 1242 | } |
1248 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
1249 | ret = rdma_fini(rhp, qhp, ep); | 1243 | ret = rdma_fini(rhp, qhp, ep); |
1250 | spin_lock_irqsave(&qhp->lock, flag); | ||
1251 | if (ret) { | 1244 | if (ret) { |
1252 | c4iw_get_ep(&ep->com); | 1245 | if (internal) |
1246 | c4iw_get_ep(&qhp->ep->com); | ||
1253 | disconnect = abort = 1; | 1247 | disconnect = abort = 1; |
1254 | goto err; | 1248 | goto err; |
1255 | } | 1249 | } |
1256 | break; | 1250 | break; |
1257 | case C4IW_QP_STATE_TERMINATE: | 1251 | case C4IW_QP_STATE_TERMINATE: |
1258 | qhp->attr.state = C4IW_QP_STATE_TERMINATE; | 1252 | set_state(qhp, C4IW_QP_STATE_TERMINATE); |
1259 | if (qhp->ibqp.uobject) | 1253 | if (qhp->ibqp.uobject) |
1260 | t4_set_wq_in_error(&qhp->wq); | 1254 | t4_set_wq_in_error(&qhp->wq); |
1261 | ep = qhp->ep; | 1255 | ep = qhp->ep; |
1262 | c4iw_get_ep(&ep->com); | ||
1263 | if (!internal) | 1256 | if (!internal) |
1264 | terminate = 1; | 1257 | terminate = 1; |
1265 | disconnect = 1; | 1258 | disconnect = 1; |
1259 | c4iw_get_ep(&qhp->ep->com); | ||
1266 | break; | 1260 | break; |
1267 | case C4IW_QP_STATE_ERROR: | 1261 | case C4IW_QP_STATE_ERROR: |
1268 | qhp->attr.state = C4IW_QP_STATE_ERROR; | 1262 | set_state(qhp, C4IW_QP_STATE_ERROR); |
1269 | if (!internal) { | 1263 | if (!internal) { |
1270 | abort = 1; | 1264 | abort = 1; |
1271 | disconnect = 1; | 1265 | disconnect = 1; |
1272 | ep = qhp->ep; | 1266 | ep = qhp->ep; |
1273 | c4iw_get_ep(&ep->com); | 1267 | c4iw_get_ep(&qhp->ep->com); |
1274 | } | 1268 | } |
1275 | goto err; | 1269 | goto err; |
1276 | break; | 1270 | break; |
@@ -1286,8 +1280,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1286 | } | 1280 | } |
1287 | switch (attrs->next_state) { | 1281 | switch (attrs->next_state) { |
1288 | case C4IW_QP_STATE_IDLE: | 1282 | case C4IW_QP_STATE_IDLE: |
1289 | flush_qp(qhp, &flag); | 1283 | flush_qp(qhp); |
1290 | qhp->attr.state = C4IW_QP_STATE_IDLE; | 1284 | set_state(qhp, C4IW_QP_STATE_IDLE); |
1291 | qhp->attr.llp_stream_handle = NULL; | 1285 | qhp->attr.llp_stream_handle = NULL; |
1292 | c4iw_put_ep(&qhp->ep->com); | 1286 | c4iw_put_ep(&qhp->ep->com); |
1293 | qhp->ep = NULL; | 1287 | qhp->ep = NULL; |
@@ -1309,7 +1303,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1309 | ret = -EINVAL; | 1303 | ret = -EINVAL; |
1310 | goto out; | 1304 | goto out; |
1311 | } | 1305 | } |
1312 | qhp->attr.state = C4IW_QP_STATE_IDLE; | 1306 | set_state(qhp, C4IW_QP_STATE_IDLE); |
1313 | break; | 1307 | break; |
1314 | case C4IW_QP_STATE_TERMINATE: | 1308 | case C4IW_QP_STATE_TERMINATE: |
1315 | if (!internal) { | 1309 | if (!internal) { |
@@ -1335,13 +1329,13 @@ err: | |||
1335 | if (!ep) | 1329 | if (!ep) |
1336 | ep = qhp->ep; | 1330 | ep = qhp->ep; |
1337 | qhp->ep = NULL; | 1331 | qhp->ep = NULL; |
1338 | qhp->attr.state = C4IW_QP_STATE_ERROR; | 1332 | set_state(qhp, C4IW_QP_STATE_ERROR); |
1339 | free = 1; | 1333 | free = 1; |
1340 | wake_up(&qhp->wait); | 1334 | wake_up(&qhp->wait); |
1341 | BUG_ON(!ep); | 1335 | BUG_ON(!ep); |
1342 | flush_qp(qhp, &flag); | 1336 | flush_qp(qhp); |
1343 | out: | 1337 | out: |
1344 | spin_unlock_irqrestore(&qhp->lock, flag); | 1338 | mutex_unlock(&qhp->mutex); |
1345 | 1339 | ||
1346 | if (terminate) | 1340 | if (terminate) |
1347 | post_terminate(qhp, NULL, internal ? GFP_ATOMIC : GFP_KERNEL); | 1341 | post_terminate(qhp, NULL, internal ? GFP_ATOMIC : GFP_KERNEL); |
@@ -1363,7 +1357,6 @@ out: | |||
1363 | */ | 1357 | */ |
1364 | if (free) | 1358 | if (free) |
1365 | c4iw_put_ep(&ep->com); | 1359 | c4iw_put_ep(&ep->com); |
1366 | |||
1367 | PDBG("%s exit state %d\n", __func__, qhp->attr.state); | 1360 | PDBG("%s exit state %d\n", __func__, qhp->attr.state); |
1368 | return ret; | 1361 | return ret; |
1369 | } | 1362 | } |
@@ -1478,6 +1471,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1478 | qhp->attr.max_ord = 1; | 1471 | qhp->attr.max_ord = 1; |
1479 | qhp->attr.max_ird = 1; | 1472 | qhp->attr.max_ird = 1; |
1480 | spin_lock_init(&qhp->lock); | 1473 | spin_lock_init(&qhp->lock); |
1474 | mutex_init(&qhp->mutex); | ||
1481 | init_waitqueue_head(&qhp->wait); | 1475 | init_waitqueue_head(&qhp->wait); |
1482 | atomic_set(&qhp->refcnt, 1); | 1476 | atomic_set(&qhp->refcnt, 1); |
1483 | 1477 | ||