aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2009-12-09 18:54:18 -0500
committerRoland Dreier <rolandd@cisco.com>2009-12-09 18:54:18 -0500
commit886f98a31586fd560fe83c44ad72e3ebe62f8e2e (patch)
treec0579b102cd6814f6aaa4f0bde6ba204bfeb03f1
parentf9f3f1e08b4d66bfda2a0c2d49a26c80489a0725 (diff)
RDMA/nes: Fix Xansation test crash on cm_node ref_count
While running a Xansation test, an active side node crashed. The problem started on the passive side, which generated an STtag that was 0. The passive side sent a TERMINATE instead of an MPA REJECT msg. The active side, receives TERMINATE and sends connect_err() and set the cm_node state to CLOSED. The passive side sends FIN + ACK after TERMINATE. Active side ends up in handle_ack_pkt() and send_reset(). send_reset() consumes 1 cm_node's ref_count. Because the cm_node is in CLOSED state, which means that cm_node will be destroyed after completion of the connect_err() indication, CM will crash after send_reset(). Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 20e21f1a18b9..a25816812ced 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1610,6 +1610,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1610 break; 1610 break;
1611 case NES_CM_STATE_CLOSED: 1611 case NES_CM_STATE_CLOSED:
1612 cleanup_retrans_entry(cm_node); 1612 cleanup_retrans_entry(cm_node);
1613 add_ref_cm_node(cm_node);
1613 send_reset(cm_node, skb); 1614 send_reset(cm_node, skb);
1614 break; 1615 break;
1615 case NES_CM_STATE_TSA: 1616 case NES_CM_STATE_TSA:
@@ -1661,9 +1662,15 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1661 passive_open_err(cm_node, skb, 1); 1662 passive_open_err(cm_node, skb, 1);
1662 break; 1663 break;
1663 case NES_CM_STATE_LISTENING: 1664 case NES_CM_STATE_LISTENING:
1665 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1666 cleanup_retrans_entry(cm_node);
1667 cm_node->state = NES_CM_STATE_CLOSED;
1668 send_reset(cm_node, skb);
1669 break;
1664 case NES_CM_STATE_CLOSED: 1670 case NES_CM_STATE_CLOSED:
1665 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); 1671 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1666 cleanup_retrans_entry(cm_node); 1672 cleanup_retrans_entry(cm_node);
1673 add_ref_cm_node(cm_node);
1667 send_reset(cm_node, skb); 1674 send_reset(cm_node, skb);
1668 break; 1675 break;
1669 case NES_CM_STATE_ESTABLISHED: 1676 case NES_CM_STATE_ESTABLISHED:
@@ -1732,8 +1739,13 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1732 dev_kfree_skb_any(skb); 1739 dev_kfree_skb_any(skb);
1733 break; 1740 break;
1734 case NES_CM_STATE_LISTENING: 1741 case NES_CM_STATE_LISTENING:
1742 cleanup_retrans_entry(cm_node);
1743 cm_node->state = NES_CM_STATE_CLOSED;
1744 send_reset(cm_node, skb);
1745 break;
1735 case NES_CM_STATE_CLOSED: 1746 case NES_CM_STATE_CLOSED:
1736 cleanup_retrans_entry(cm_node); 1747 cleanup_retrans_entry(cm_node);
1748 add_ref_cm_node(cm_node);
1737 send_reset(cm_node, skb); 1749 send_reset(cm_node, skb);
1738 break; 1750 break;
1739 case NES_CM_STATE_LAST_ACK: 1751 case NES_CM_STATE_LAST_ACK:
@@ -2193,8 +2205,11 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
2193 case NES_CM_STATE_CLOSING: 2205 case NES_CM_STATE_CLOSING:
2194 ret = -1; 2206 ret = -1;
2195 break; 2207 break;
2196 case NES_CM_STATE_MPAREJ_RCVD:
2197 case NES_CM_STATE_LISTENING: 2208 case NES_CM_STATE_LISTENING:
2209 cleanup_retrans_entry(cm_node);
2210 send_reset(cm_node, NULL);
2211 break;
2212 case NES_CM_STATE_MPAREJ_RCVD:
2198 case NES_CM_STATE_UNKNOWN: 2213 case NES_CM_STATE_UNKNOWN:
2199 case NES_CM_STATE_INITED: 2214 case NES_CM_STATE_INITED:
2200 case NES_CM_STATE_CLOSED: 2215 case NES_CM_STATE_CLOSED: