[ewg] [PATCH 10/10] nes: connection timeout and reset fix

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Thu Dec 20 12:39:20 PST 2007


Fixed the timeout for connection setup and properly
handle connection reset in the event of a timeout.
Prior to this patch connections would timeout too
quickly and no reset would occur.

Signed-off-by: Glenn Grundstrom <ggrundstrom at neteffect.com>

---

diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 1777769..bdca2dd 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -714,6 +714,7 @@ int send_reset(struct nes_cm_node *cm_node)
 {
 	int ret;
 	struct sk_buff *skb = get_free_pkt(cm_node);
+	int flags = SET_RST | SET_ACK;
 
 	if (!skb) {
 		nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
@@ -721,7 +722,7 @@ int send_reset(struct nes_cm_node *cm_node)
 	}
 
 	add_ref_cm_node(cm_node);
-	form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_RST | SET_ACK);
+	form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
 	ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1);
 
 	return ret;
@@ -1279,6 +1280,10 @@ int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	int ret = 0;
 	struct tcphdr *tcph = tcp_hdr(skb);
 	u32 inc_sequence;
+	if (cm_node->state == NES_CM_STATE_SYN_SENT && tcph->syn) {
+		inc_sequence = ntohl(tcph->seq);
+		cm_node->tcp_cntxt.rcv_nxt = inc_sequence;
+	}
 
 	if ((!tcph) || (cm_node->state == NES_CM_STATE_TSA)) {
 		BUG_ON(!tcph);
@@ -1337,7 +1342,8 @@ int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 			cm_node->tcp_cntxt.rcv_nxt, (tcph->syn ? "SYN":""),
 			(tcph->ack ? "ACK":""));
 
-	if (!tcph->syn && (inc_sequence != cm_node->tcp_cntxt.rcv_nxt)) {
+	if (!tcph->syn && (inc_sequence != cm_node->tcp_cntxt.rcv_nxt)
+		) {
 		nes_debug(NES_DBG_CM, "dropping packet, datasize = %u, sequence = 0x%08X,"
 				" ack_seq = 0x%08X, rcv_nxt = 0x%08X Flags: %s.\n",
 				datasize, inc_sequence,ntohl(tcph->ack_seq),
@@ -1353,7 +1359,12 @@ int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 
 	if (optionsize) {
 		u8 *optionsloc = (u8 *)&tcph[1];
-		process_options(cm_node, optionsloc, optionsize);
+		if (process_options(cm_node, optionsloc, optionsize, (u32)tcph->syn)) {
+			nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", __FUNCTION__, cm_node);
+			send_reset(cm_node);
+			rem_ref_cm_node(cm_core, cm_node);
+			return 0;
+		}
 	}
 	else if (tcph->syn)
 		cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS;
@@ -1371,8 +1382,8 @@ int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 			case NES_CM_STATE_SYN_RCVD:
 			case NES_CM_STATE_SYN_SENT:
 				/* read and stash current sequence number */
-				if (cm_node->tcp_cntxt.rem_ack_num > cm_node->tcp_cntxt.loc_seq_num) {
-					nes_debug(NES_DBG_CM, "ERROR - cm_node->tcp_cntxt.rem_ack_num >"
+				if (cm_node->tcp_cntxt.rem_ack_num != cm_node->tcp_cntxt.loc_seq_num) {
+					nes_debug(NES_DBG_CM, "ERROR - cm_node->tcp_cntxt.rem_ack_num !="
 							" cm_node->tcp_cntxt.loc_seq_num\n");
 					send_reset(cm_node);
 					return 0;
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index c511242..46f1dea 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -136,7 +136,7 @@ struct nes_timer_entry {
 #ifdef CONFIG_INFINIBAND_NES_DEBUG
 #define NES_RETRY_TIMEOUT   (1000*HZ/1000)
 #else
-#define NES_RETRY_TIMEOUT   (1000*HZ/10000)
+#define NES_RETRY_TIMEOUT   (3000*HZ/1000)
 #endif
 #define NES_SHORT_TIME      (10)
 #define NES_LONG_TIME       (2000*HZ/1000)



More information about the ewg mailing list