[ewg] [PATCH 2/5] nes: provider listener cleanup

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Fri Nov 30 10:09:21 PST 2007


If an error occurs during the provider listen call the reference
count can be off.  This will prevent the listener from being
destroyed properly.

This is fixed by correcting the reference counts when a
problem is detected.

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 3005cb1..933f31c 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -668,7 +668,7 @@ int send_syn(struct nes_cm_node *cm_node, u32 sendack)
 	options = (union all_known_options *)&optionsbuffer[optionssize];
 	options->as_windowscale.optionnum = OPTION_NUMBER_WINDOW_SCALE;
 	options->as_windowscale.length = sizeof(struct option_windowscale);
-	options->as_windowscale.shiftcount = cm_node->tcp_cntxt.snd_wscale;
+	options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale;
 	optionssize += sizeof(struct option_windowscale);
 
 	if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt)
@@ -1387,15 +1387,12 @@ int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 			case NES_CM_STATE_CLOSED:
 				break;
 			case NES_CM_STATE_LISTENING:
-				if (!(tcph->syn)) {
-					nes_debug(NES_DBG_CM, "Received an ack without a SYN on a listening port\n");
-					send_reset(cm_node);
-					/* send_reset bumps refcount, this should have been a new node */
-					rem_ref_cm_node(cm_core, cm_node);
-					return -1;
-				} else {
-					nes_debug(NES_DBG_CM, "Received an ack on a listening port (syn-ack maybe?)\n");
-				}
+				nes_debug(NES_DBG_CM, "Received an ACK on a listening port (SYN %d)\n", tcph->syn);
+				cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
+				send_reset(cm_node);
+				/* send_reset bumps refcount, this should have been a new node */
+				rem_ref_cm_node(cm_core, cm_node);
+				return -1;
 				break;
 			case NES_CM_STATE_TSA:
 				nes_debug(NES_DBG_CM, "Received a packet with the ack bit set while in TSA state\n");
@@ -1832,6 +1829,10 @@ int mini_cm_recv_pkt(struct nes_cm_core *cm_core, struct nes_vnic *nesvnic,
 		cm_node = make_cm_node(cm_core, nesvnic, &nfo, listener);
 		if (!cm_node) {
 			nes_debug(NES_DBG_CM, "Unable to allocate node\n");
+			if (listener) {
+				nes_debug(NES_DBG_CM, "unable to allocate node and decrementing listener refcount\n");
+				atomic_dec(&listener->ref_count);
+			}
 			ret = -1;
 			goto out;
 		}



More information about the ewg mailing list