aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2010-07-23 15:12:37 -0400
committerRoland Dreier <rolandd@cisco.com>2010-08-03 00:06:17 -0400
commitca5a22028d0845dd6bcce0dce12a7beda315baf0 (patch)
tree240d5d5973dc07f0d2e3959794a446ac0ca93546 /drivers/infiniband/hw
parentd4f1a5c6efabccd4b787a8b5907a5df9204ad2f6 (diff)
RDMA/cxgb4: Set/reset the EP timer inside EP lock
Endpoint timer manipulation needs to be done inside the lock. Otherwise we can get into a situation where a timer is stopped before it is started, which hits the WARN_ON() in stop_ep_timer(). Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c34
1 files changed, 8 insertions, 26 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index ffdc308151c..3eff5df6d40 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -1484,8 +1484,6 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
1484 int closing = 0; 1484 int closing = 0;
1485 struct tid_info *t = dev->rdev.lldi.tids; 1485 struct tid_info *t = dev->rdev.lldi.tids;
1486 unsigned int tid = GET_TID(hdr); 1486 unsigned int tid = GET_TID(hdr);
1487 int start_timer = 0;
1488 int stop_timer = 0;
1489 1487
1490 ep = lookup_tid(t, tid); 1488 ep = lookup_tid(t, tid);
1491 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); 1489 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
@@ -1522,7 +1520,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
1522 wake_up(&ep->com.waitq); 1520 wake_up(&ep->com.waitq);
1523 break; 1521 break;
1524 case FPDU_MODE: 1522 case FPDU_MODE:
1525 start_timer = 1; 1523 start_ep_timer(ep);
1526 __state_set(&ep->com, CLOSING); 1524 __state_set(&ep->com, CLOSING);
1527 closing = 1; 1525 closing = 1;
1528 peer_close_upcall(ep); 1526 peer_close_upcall(ep);
@@ -1535,7 +1533,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
1535 disconnect = 0; 1533 disconnect = 0;
1536 break; 1534 break;
1537 case MORIBUND: 1535 case MORIBUND:
1538 stop_timer = 1; 1536 stop_ep_timer(ep);
1539 if (ep->com.cm_id && ep->com.qp) { 1537 if (ep->com.cm_id && ep->com.qp) {
1540 attrs.next_state = C4IW_QP_STATE_IDLE; 1538 attrs.next_state = C4IW_QP_STATE_IDLE;
1541 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, 1539 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
@@ -1558,10 +1556,6 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
1558 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, 1556 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1559 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); 1557 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1560 } 1558 }
1561 if (start_timer)
1562 start_ep_timer(ep);
1563 if (stop_timer)
1564 stop_ep_timer(ep);
1565 if (disconnect) 1559 if (disconnect)
1566 c4iw_ep_disconnect(ep, 0, GFP_KERNEL); 1560 c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
1567 if (release) 1561 if (release)
@@ -1590,7 +1584,6 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
1590 unsigned long flags; 1584 unsigned long flags;
1591 struct tid_info *t = dev->rdev.lldi.tids; 1585 struct tid_info *t = dev->rdev.lldi.tids;
1592 unsigned int tid = GET_TID(req); 1586 unsigned int tid = GET_TID(req);
1593 int stop_timer = 0;
1594 1587
1595 ep = lookup_tid(t, tid); 1588 ep = lookup_tid(t, tid);
1596 if (is_neg_adv_abort(req->status)) { 1589 if (is_neg_adv_abort(req->status)) {
@@ -1605,10 +1598,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
1605 case CONNECTING: 1598 case CONNECTING:
1606 break; 1599 break;
1607 case MPA_REQ_WAIT: 1600 case MPA_REQ_WAIT:
1608 stop_timer = 1; 1601 stop_ep_timer(ep);
1609 break; 1602 break;
1610 case MPA_REQ_SENT: 1603 case MPA_REQ_SENT:
1611 stop_timer = 1; 1604 stop_ep_timer(ep);
1612 connect_reply_upcall(ep, -ECONNRESET); 1605 connect_reply_upcall(ep, -ECONNRESET);
1613 break; 1606 break;
1614 case MPA_REP_SENT: 1607 case MPA_REP_SENT:
@@ -1632,7 +1625,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
1632 break; 1625 break;
1633 case MORIBUND: 1626 case MORIBUND:
1634 case CLOSING: 1627 case CLOSING:
1635 stop_timer = 1; 1628 stop_ep_timer(ep);
1636 /*FALLTHROUGH*/ 1629 /*FALLTHROUGH*/
1637 case FPDU_MODE: 1630 case FPDU_MODE:
1638 if (ep->com.cm_id && ep->com.qp) { 1631 if (ep->com.cm_id && ep->com.qp) {
@@ -1678,8 +1671,6 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
1678 rpl->cmd = CPL_ABORT_NO_RST; 1671 rpl->cmd = CPL_ABORT_NO_RST;
1679 c4iw_ofld_send(&ep->com.dev->rdev, rpl_skb); 1672 c4iw_ofld_send(&ep->com.dev->rdev, rpl_skb);
1680out: 1673out:
1681 if (stop_timer)
1682 stop_ep_timer(ep);
1683 if (release) 1674 if (release)
1684 release_ep_resources(ep); 1675 release_ep_resources(ep);
1685 return 0; 1676 return 0;
@@ -1694,7 +1685,6 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1694 int release = 0; 1685 int release = 0;
1695 struct tid_info *t = dev->rdev.lldi.tids; 1686 struct tid_info *t = dev->rdev.lldi.tids;
1696 unsigned int tid = GET_TID(rpl); 1687 unsigned int tid = GET_TID(rpl);
1697 int stop_timer = 0;
1698 1688
1699 ep = lookup_tid(t, tid); 1689 ep = lookup_tid(t, tid);
1700 1690
@@ -1708,7 +1698,7 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1708 __state_set(&ep->com, MORIBUND); 1698 __state_set(&ep->com, MORIBUND);
1709 break; 1699 break;
1710 case MORIBUND: 1700 case MORIBUND:
1711 stop_timer = 1; 1701 stop_ep_timer(ep);
1712 if ((ep->com.cm_id) && (ep->com.qp)) { 1702 if ((ep->com.cm_id) && (ep->com.qp)) {
1713 attrs.next_state = C4IW_QP_STATE_IDLE; 1703 attrs.next_state = C4IW_QP_STATE_IDLE;
1714 c4iw_modify_qp(ep->com.qp->rhp, 1704 c4iw_modify_qp(ep->com.qp->rhp,
@@ -1728,8 +1718,6 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1728 break; 1718 break;
1729 } 1719 }
1730 spin_unlock_irqrestore(&ep->com.lock, flags); 1720 spin_unlock_irqrestore(&ep->com.lock, flags);
1731 if (stop_timer)
1732 stop_ep_timer(ep);
1733 if (release) 1721 if (release)
1734 release_ep_resources(ep); 1722 release_ep_resources(ep);
1735 return 0; 1723 return 0;
@@ -2108,8 +2096,6 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
2108 int close = 0; 2096 int close = 0;
2109 int fatal = 0; 2097 int fatal = 0;
2110 struct c4iw_rdev *rdev; 2098 struct c4iw_rdev *rdev;
2111 int start_timer = 0;
2112 int stop_timer = 0;
2113 2099
2114 spin_lock_irqsave(&ep->com.lock, flags); 2100 spin_lock_irqsave(&ep->com.lock, flags);
2115 2101
@@ -2133,7 +2119,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
2133 ep->com.state = ABORTING; 2119 ep->com.state = ABORTING;
2134 else { 2120 else {
2135 ep->com.state = CLOSING; 2121 ep->com.state = CLOSING;
2136 start_timer = 1; 2122 start_ep_timer(ep);
2137 } 2123 }
2138 set_bit(CLOSE_SENT, &ep->com.flags); 2124 set_bit(CLOSE_SENT, &ep->com.flags);
2139 break; 2125 break;
@@ -2141,7 +2127,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
2141 if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) { 2127 if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {
2142 close = 1; 2128 close = 1;
2143 if (abrupt) { 2129 if (abrupt) {
2144 stop_timer = 1; 2130 stop_ep_timer(ep);
2145 ep->com.state = ABORTING; 2131 ep->com.state = ABORTING;
2146 } else 2132 } else
2147 ep->com.state = MORIBUND; 2133 ep->com.state = MORIBUND;
@@ -2159,10 +2145,6 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
2159 } 2145 }
2160 2146
2161 spin_unlock_irqrestore(&ep->com.lock, flags); 2147 spin_unlock_irqrestore(&ep->com.lock, flags);
2162 if (start_timer)
2163 start_ep_timer(ep);
2164 if (stop_timer)
2165 stop_ep_timer(ep);
2166 if (close) { 2148 if (close) {
2167 if (abrupt) 2149 if (abrupt)
2168 ret = abort_connection(ep, NULL, gfp); 2150 ret = abort_connection(ep, NULL, gfp);