[openib-general] [PATCH] CM: associate sends with current CEP state

Sean Hefty mshefty at ichips.intel.com
Tue Jan 18 14:53:57 PST 2005


Committing patch that will associate sends with the current
communication identifier state.  Fixes a race condition completing
a send in failure with receiving a response.  Also added calls to
cancel sends once response is received.

- Sean

signed-off-by: Sean Hefty <sean.hefty at intel.com>

Index: core/cm.c
===================================================================
--- core/cm.c	(revision 1567)
+++ core/cm.c	(working copy)
@@ -81,6 +81,7 @@
 	struct cm_id_private *cm_id_priv;
 	struct ib_send_wr send_wr;
 	struct ib_sge sge;
+	enum ib_cm_state sent_state;
 	u8 retry;
 	DECLARE_PCI_UNMAP_ADDR(mapping)
 	struct ib_mad mad;
@@ -768,6 +769,7 @@
 		goto out;
 	}
 	cm_id->state = IB_CM_REQ_SENT;
+	msg->sent_state = IB_CM_REQ_SENT;
 	cm_id_priv->msg = msg;
 
 	if (param->peer_to_peer) {
@@ -904,8 +906,8 @@
 		cm_insert_remote_id(cur_cm_id_priv);
 		spin_unlock_irqrestore(&cm.lock, flags);
 
-		ib_cancel_mad(cur_cm_id_priv->port->mad_agent,
-			      (unsigned long)cur_cm_id_priv->msg);
+		ib_cancel_mad(port->mad_agent,
+			      (unsigned long) cur_cm_id_priv->msg);
 		ib_destroy_cm_id(&cm_id_priv->id);
 		cm_id_priv = cur_cm_id_priv;
 	}
@@ -1029,6 +1031,7 @@
 	}
 
 	cm_id->state = IB_CM_REP_SENT;
+	msg->sent_state = IB_CM_REP_SENT;
 	cm_id_priv->msg = msg;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 out:
@@ -1145,6 +1148,8 @@
 	cm_id_priv->id.state = IB_CM_REP_RCVD;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
+	ib_cancel_mad(port->mad_agent, (unsigned long) cm_id_priv->msg);
+
 	cm_id_priv->id.remote_id = rep_msg->local_comm_id;
 	cm_id_priv->remote_ca_guid = rep_msg->local_ca_guid;
 	cm_id_priv->remote_qpn = cm_rep_get_local_qpn(rep_msg);
@@ -1201,6 +1206,8 @@
 	cm_id_priv->id.state = IB_CM_ESTABLISHED;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
+	ib_cancel_mad(port->mad_agent, (unsigned long) cm_id_priv->msg);
+
 	cm_event->event = IB_CM_RTU_RECEIVED;
 	cm_event->private_data = &rtu_msg->private_data;
 	cm_id_priv->id.cm_handler(&cm_id_priv->id, cm_event);
@@ -1287,6 +1294,7 @@
 	}
 
 	cm_id->state = IB_CM_DREQ_SENT;
+	msg->sent_state = IB_CM_DREQ_SENT;
 	cm_id_priv->msg = msg;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 out:
@@ -1418,6 +1426,8 @@
 	cm_id_priv->id.state = IB_CM_TIMEWAIT;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
+	ib_cancel_mad(port->mad_agent, (unsigned long) cm_id_priv->msg);
+
 	cm_event->event = IB_CM_DREP_RECEIVED;
 	cm_event->private_data = &drep_msg->private_data;
 	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, cm_event);
@@ -1514,7 +1524,6 @@
 	}
 
 	cm_id->state = IB_CM_IDLE;
-	cm_id_priv->msg = msg;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 out:
 	return ret;
@@ -1621,7 +1630,6 @@
 	default:
 		break;
 	}
-	cm_id_priv->msg = msg;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 out:
 	return ret;
@@ -1704,6 +1712,7 @@
 	}
 
 	cm_id->lap_state = IB_CM_LAP_SENT;
+	msg->sent_state = IB_CM_ESTABLISHED;
 	cm_id_priv->msg = msg;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 out:
@@ -1858,6 +1867,7 @@
 {
 	struct cm_id_private *cm_id_priv;
 	struct cm_apr_msg *apr_msg;
+	struct cm_msg *msg;
 	struct ib_cm_event *cm_event;
 	unsigned long flags;
 
@@ -1878,10 +1888,11 @@
 		goto out;
 	}
 	cm_id_priv->id.lap_state = IB_CM_LAP_IDLE;
+	msg = cm_id_priv->msg;
+	cm_id_priv->msg = NULL;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
-	ib_cancel_mad(cm_id_priv->port->mad_agent,
-		      (unsigned long)cm_id_priv->msg);
+	ib_cancel_mad(port->mad_agent, (unsigned long) msg);
 
 	cm_event->event = IB_CM_APR_RECEIVED;
 	cm_event->param.apr_rcvd.ap_status = apr_msg->ap_status;
@@ -1959,6 +1970,7 @@
 		goto out;
 	}
 	cm_id->state = IB_CM_SIDR_REQ_SENT;
+	msg->sent_state = IB_CM_SIDR_REQ_SENT;
 	cm_id_priv->msg = msg;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 out:
@@ -2127,8 +2139,7 @@
 	cm_id_priv->id.state = IB_CM_IDLE;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
-	ib_cancel_mad(cm_id_priv->port->mad_agent,
-		      (unsigned long)cm_id_priv->msg);
+	ib_cancel_mad(port->mad_agent, (unsigned long) cm_id_priv->msg);
 
 	cm_event->event = IB_CM_SIDR_REP_RECEIVED;
 	cm_event->param.sidr_rep_rcvd.status = sidr_rep_msg->status;
@@ -2162,7 +2173,7 @@
 
 	/* Discard old sends or ones without a response. */
 	spin_lock_irqsave(&cm_id_priv->lock, flags);
-	if (msg != cm_id_priv->msg)
+	if (msg != cm_id_priv->msg || msg->sent_state != cm_id_priv->id.state)
 		goto discard;
 
 	switch (cm_id_priv->id.state) {
@@ -2207,7 +2218,7 @@
 
 	/* Discard old sends. */
 	spin_lock_irqsave(&cm_id_priv->lock, flags);
-	if (msg != cm_id_priv->msg) {
+	if (msg != cm_id_priv->msg || msg->sent_state != cm_id_priv->id.state) {
 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 		cm_free_msg(msg);
 		return;
 



More information about the general mailing list