diff options
author | Steve Wise <swise@opengridcomputing.com> | 2009-09-05 23:22:38 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-09-05 23:22:38 -0400 |
commit | a52bf98d99e922363d1d600a79de6aaf00090d47 (patch) | |
tree | d18ba723a8a4ff79de68c96261ef32fc838e5bcb /drivers/infiniband | |
parent | 6e47fe43502ba6dfe86d556661795d9bb0361309 (diff) |
RDMA/cxgb3: Wake up any waiters on peer close/abort
A close/abort while waiting for a wr_ack during connection migration
can cause a hung process in iwch_accept_cr/iwch_reject_cr.
The fix is to set rpl_error/rpl_done and wake up the waiters when we
get a close/abort while in MPA_REQ_RCVD state.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 7f22f1797718..66b41351910a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -1478,9 +1478,14 @@ static int peer_close(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1478 | /* | 1478 | /* |
1479 | * We're gonna mark this puppy DEAD, but keep | 1479 | * We're gonna mark this puppy DEAD, but keep |
1480 | * the reference on it until the ULP accepts or | 1480 | * the reference on it until the ULP accepts or |
1481 | * rejects the CR. | 1481 | * rejects the CR. Also wake up anyone waiting |
1482 | * in rdma connection migration (see iwch_accept_cr()). | ||
1482 | */ | 1483 | */ |
1483 | __state_set(&ep->com, CLOSING); | 1484 | __state_set(&ep->com, CLOSING); |
1485 | ep->com.rpl_done = 1; | ||
1486 | ep->com.rpl_err = -ECONNRESET; | ||
1487 | PDBG("waking up ep %p\n", ep); | ||
1488 | wake_up(&ep->com.waitq); | ||
1484 | break; | 1489 | break; |
1485 | case MPA_REP_SENT: | 1490 | case MPA_REP_SENT: |
1486 | __state_set(&ep->com, CLOSING); | 1491 | __state_set(&ep->com, CLOSING); |
@@ -1588,8 +1593,13 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1588 | /* | 1593 | /* |
1589 | * We're gonna mark this puppy DEAD, but keep | 1594 | * We're gonna mark this puppy DEAD, but keep |
1590 | * the reference on it until the ULP accepts or | 1595 | * the reference on it until the ULP accepts or |
1591 | * rejects the CR. | 1596 | * rejects the CR. Also wake up anyone waiting |
1597 | * in rdma connection migration (see iwch_accept_cr()). | ||
1592 | */ | 1598 | */ |
1599 | ep->com.rpl_done = 1; | ||
1600 | ep->com.rpl_err = -ECONNRESET; | ||
1601 | PDBG("waking up ep %p\n", ep); | ||
1602 | wake_up(&ep->com.waitq); | ||
1593 | break; | 1603 | break; |
1594 | case MORIBUND: | 1604 | case MORIBUND: |
1595 | case CLOSING: | 1605 | case CLOSING: |
@@ -1828,8 +1838,6 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
1828 | ep->com.cm_id = cm_id; | 1838 | ep->com.cm_id = cm_id; |
1829 | ep->com.qp = qp; | 1839 | ep->com.qp = qp; |
1830 | 1840 | ||
1831 | ep->com.rpl_done = 0; | ||
1832 | ep->com.rpl_err = 0; | ||
1833 | ep->ird = conn_param->ird; | 1841 | ep->ird = conn_param->ird; |
1834 | ep->ord = conn_param->ord; | 1842 | ep->ord = conn_param->ord; |
1835 | 1843 | ||