[openib-general] [PATCH] [CM] fix unload issue, crash rejecting a REQ after an error

Sean Hefty mshefty at ichips.intel.com
Wed Mar 9 10:20:11 PST 2005


This patch fixes the CM unload issue added by the previous patch.  It
should also allow sending a REJ message in response to a REQ after
an error has occurred.

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


Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c	(revision 1965)
+++ infiniband/core/cm.c	(working copy)
@@ -232,7 +232,16 @@ static void cm_set_ah_attr(struct ib_ah_
 	ah_attr->port_num = port_num;
 }
 
-static int cm_init_av(struct ib_sa_path_rec *path, struct cm_av *av)
+static void cm_init_av_for_response(struct cm_port *port,
+				    struct ib_wc *wc, struct cm_av *av)
+{
+	av->port = port;
+	av->pkey_index = wc->pkey_index;
+	cm_set_ah_attr(&av->ah_attr, port->port_num, wc->slid, wc->sl,
+		       wc->dlid_path_bits);
+}
+
+static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
 {
 	struct cm_device *cm_dev;
 	struct cm_port *port = NULL;
@@ -259,7 +268,6 @@ static int cm_init_av(struct ib_sa_path_
 		return ret;
 
 	av->port = port;
-	av->dgid = path->dgid;
 	cm_set_ah_attr(&av->ah_attr, av->port->port_num, path->dlid,
 		       path->sl, path->slid & 0x7F);
 	return 0;
@@ -819,11 +827,12 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
 	}
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
-	ret = cm_init_av(param->primary_path, &cm_id_priv->av);
+	ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av);
 	if (ret)
 		goto out;
 	if (param->alternate_path) {
-		ret = cm_init_av(param->alternate_path, &cm_id_priv->alt_av);
+		ret = cm_init_av_by_path(param->alternate_path,
+					 &cm_id_priv->alt_av);
 		if (ret)
 			goto out;
 	}
@@ -1012,6 +1021,8 @@ static int cm_req_handler(struct cm_work
 
 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
 	cm_id_priv->id.remote_id = req_msg->local_comm_id;
+	cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+				&cm_id_priv->av);
 	cm_id_priv->timewait_info = cm_create_timewait_info(
 						cm_id_priv->id.local_id,
 						cm_id_priv->id.remote_id,
@@ -1056,11 +1067,11 @@ static int cm_req_handler(struct cm_work
 	cm_id_priv->id.service_mask = ~0ULL;
 
 	cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
-	ret = cm_init_av(&work->path[0], &cm_id_priv->av);
+	ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
 	if (ret)
 		goto error3;
 	if (req_msg->alt_local_lid) {
-		ret = cm_init_av(&work->path[1], &cm_id_priv->alt_av);
+		ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av);
 		if (ret)
 			goto error3;
 	}
@@ -2287,7 +2298,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id 
 		return -EINVAL;
 
 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
-	ret = cm_init_av(param->path, &cm_id_priv->av);
+	ret = cm_init_av_by_path(param->path, &cm_id_priv->av);
 	if (ret)
 		goto out;
 
@@ -2359,6 +2370,8 @@ static int cm_sidr_req_handler(struct cm
 	wc = work->mad_recv_wc->wc;
 	cm_id_priv->av.dgid.global.subnet_prefix = wc->slid;
 	cm_id_priv->av.dgid.global.interface_id = 0;
+	cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+				&cm_id_priv->av);
 	cm_id_priv->id.remote_id = sidr_req_msg->request_id;
 	cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD;
 	atomic_inc(&cm_id_priv->work_count);
@@ -2383,10 +2396,6 @@ static int cm_sidr_req_handler(struct cm
 	cm_id_priv->id.context = cur_cm_id_priv->id.context;
 	cm_id_priv->id.service_id = sidr_req_msg->service_id;
 	cm_id_priv->id.service_mask = ~0ULL;
-	cm_id_priv->av.port = work->port;
-	cm_id_priv->av.pkey_index = wc->pkey_index;
-	cm_set_ah_attr(&cm_id_priv->av.ah_attr, work->port->port_num,
-		       wc->slid, wc->sl, wc->dlid_path_bits);
 
 	cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
 	cm_process_work(cm_id_priv, work);
@@ -3013,7 +3022,8 @@ static void cm_remove_one(struct ib_devi
 	write_unlock_irqrestore(&cm.device_lock, flags);
 
 	for (i = 1; i <= device->phys_port_cnt; i++) {
-		port = &cm_dev->port[i];
+		port = &cm_dev->port[i-1];
+		ib_dereg_mr(port->mr);
 		ib_modify_port(device, port->port_num, 0, &port_modify);
 		ib_unregister_mad_agent(port->mad_agent);
 	}



More information about the general mailing list