[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