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 <[EMAIL PROTECTED]>


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);
        }
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to