[openib-general] [PATCH] [CM] repeat private data with MRA, RTU, DREP messages

Sean Hefty sean.hefty at intel.com
Tue May 24 12:46:16 PDT 2005


The following patch finishes adding in support to repeat
user-specified private data in MRA, RTU, and DREP messages.

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



Index: cm.c
===================================================================
--- cm.c	(revision 2460)
+++ cm.c	(working copy)
@@ -219,6 +219,32 @@ static void cm_free_msg(struct ib_mad_se
 	ib_free_send_mad(msg);
 }
 
+static void * cm_copy_private_data(const void *private_data,
+				   u8 private_data_len)
+{
+	void *data;
+
+	if (!private_data || !private_data_len)
+		return NULL;
+
+	data = kmalloc(private_data_len, GFP_KERNEL);
+	if (!data)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(data, private_data, private_data_len);
+	return data;
+}
+
+static void cm_set_private_data(struct cm_id_private *cm_id_priv,
+				 void *private_data, u8 private_data_len)
+{
+	if (cm_id_priv->private_data && cm_id_priv->private_data_len)
+		kfree(cm_id_priv->private_data);
+
+	cm_id_priv->private_data = private_data;
+	cm_id_priv->private_data_len = private_data_len;
+}
+
 static void cm_set_ah_attr(struct ib_ah_attr *ah_attr, u8 port_num,
 			   u16 dlid, u8 sl, u16 src_path_bits)
 {
@@ -672,6 +698,8 @@ retest:
 	wait_event(cm_id_priv->wait, !atomic_read(&cm_id_priv->refcount));
 	while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
 		cm_free_work(work);
+	if (cm_id_priv->private_data && cm_id_priv->private_data_len)
+		kfree(cm_id_priv->private_data);
 	kfree(cm_id_priv);
 }
 EXPORT_SYMBOL(ib_destroy_cm_id);
@@ -1373,6 +1401,7 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_i
 	struct ib_mad_send_buf *msg;
 	struct ib_send_wr *bad_send_wr;
 	unsigned long flags;
+	void *data;
 	int ret;
 
 	if (private_data && private_data_len > IB_CM_RTU_PRIVATE_DATA_SIZE)
@@ -1381,7 +1410,13 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_i
 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
 	ret = cm_alloc_msg(cm_id_priv, &msg);
 	if (ret)
-		goto out;
+		return ret;
+
+	data = cm_copy_private_data(private_data, private_data_len);
+	if (IS_ERR(data)) {
+		ret = PTR_ERR(data);
+		goto error1;
+	}
 
 	cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
 		      private_data, private_data_len);
@@ -1394,15 +1429,17 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_i
 	else
 		ret = -EINVAL;
 
-	if (ret) {
-		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-		cm_free_msg(msg);
-		goto out;
-	}
+	if (ret)
+		goto error2;
 
 	cm_id->state = IB_CM_ESTABLISHED;
+	cm_set_private_data(cm_id_priv, data, private_data_len);
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-out:
+	return 0;
+
+error2:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	kfree(data);
+error1:	cm_free_msg(msg);
 	return ret;
 }
 EXPORT_SYMBOL(ib_send_cm_rtu);
@@ -1706,31 +1743,51 @@ int ib_send_cm_drep(struct ib_cm_id *cm_
 	struct ib_mad_send_buf *msg;
 	struct ib_send_wr *bad_send_wr;
 	unsigned long flags;
-	int msg_ret, ret;
+	void *data;
+	int ret;
 
 	if (private_data && private_data_len > IB_CM_DREP_PRIVATE_DATA_SIZE)
 		return -EINVAL;
 
 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
-	msg_ret = cm_alloc_msg(cm_id_priv, &msg);
-	if (!msg_ret)
-		cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
-			       private_data, private_data_len);
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto error1;
+
+	data = cm_copy_private_data(private_data, private_data_len);
+	if (IS_ERR(data)) {
+		ret = PTR_ERR(data);
+		goto error2;
+	}
+
+	cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
+		       private_data, private_data_len);
 
 	spin_lock_irqsave(&cm_id_priv->lock, flags);
 	if (cm_id->state != IB_CM_DREQ_RCVD) {
 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-		ret = -EINVAL;
-		goto out;
+		cm_free_msg(msg);
+		kfree(data);
+		return -EINVAL;
 	}
-	ret = msg_ret ? msg_ret :
-		ib_post_send_mad(cm_id_priv->av.port->mad_agent,
-				 &msg->send_wr, &bad_send_wr);
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+			       &bad_send_wr);
+	if (ret)
+		cm_free_msg(msg);
+
+	cm_set_private_data(cm_id_priv, data, private_data_len);
 	cm_enter_timewait(cm_id_priv);
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-out:
-	if (!msg_ret && ret)
-		cm_free_msg(msg);
+	return ret;
+
+error2:
+	cm_free_msg(msg);
+error1:
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state == IB_CM_DREQ_RCVD)
+		cm_enter_timewait(cm_id_priv);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 	return ret;
 }
 EXPORT_SYMBOL(ib_send_cm_drep);
@@ -2005,6 +2062,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
 	struct cm_id_private *cm_id_priv;
 	struct ib_mad_send_buf *msg;
 	struct ib_send_wr *bad_send_wr;
+	void *data;
 	unsigned long flags;
 	int ret;
 
@@ -2016,6 +2074,12 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
 	if (ret)
 		return ret;
 
+	data = cm_copy_private_data(private_data, private_data_len);
+	if (IS_ERR(data)) {
+		ret = PTR_ERR(data);
+		goto error1;
+	}
+
 	spin_lock_irqsave(&cm_id_priv->lock, flags);
 	switch(cm_id_priv->id.state) {
 	case IB_CM_REQ_RCVD:
@@ -2025,7 +2089,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
 		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
 				       &msg->send_wr, &bad_send_wr);
 		if (ret)
-			goto error;
+			goto error2;
 		cm_id->state = IB_CM_MRA_REQ_SENT;
 		break;
 	case IB_CM_REP_RCVD:
@@ -2035,7 +2099,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
 		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
 				       &msg->send_wr, &bad_send_wr);
 		if (ret)
-			goto error;
+			goto error2;
 		cm_id->state = IB_CM_MRA_REP_SENT;
 		break;
 	case IB_CM_ESTABLISHED:
@@ -2045,19 +2109,21 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
 		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
 				       &msg->send_wr, &bad_send_wr);
 		if (ret)
-			goto error;
+			goto error2;
 		cm_id->lap_state = IB_CM_MRA_LAP_SENT;
 		break;
 	default:
 		ret = -EINVAL;
-		goto error;
+		goto error2;
 	}
 	cm_id_priv->service_timeout = service_timeout;
+	cm_set_private_data(cm_id_priv, data, private_data_len);
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 	return 0;
 
-error:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-	cm_free_msg(msg);
+error2:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	kfree(data);
+error1:	cm_free_msg(msg);
 	return ret;
 }
 EXPORT_SYMBOL(ib_send_cm_mra);






More information about the general mailing list