IB/cm: Store and restore ah_attr during LAP msg processing
authorParav Pandit <parav@mellanox.com>
Mon, 14 May 2018 08:11:08 +0000 (11:11 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 16 May 2018 20:11:46 +0000 (14:11 -0600)
During CM LAP processing, ah_attr is reinitialized on receiving LAP
request. First likely during CM request processing.

ah_attr might get zero out if LAP processing fails.
Therefore, attempt to create new ah_attr for the LAP message.
If the initialization fails, continue with older ah_attr.
If the initialization passes, consider the new ah_attr by overwriting
the older one.

Signed-off-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/cm.c

index 34b4def..8b640cb 100644 (file)
@@ -452,6 +452,32 @@ static void cm_set_private_data(struct cm_id_private *cm_id_priv,
        cm_id_priv->private_data_len = private_data_len;
 }
 
+static int cm_init_av_for_lap(struct cm_port *port, struct ib_wc *wc,
+                             struct ib_grh *grh, struct cm_av *av)
+{
+       struct rdma_ah_attr new_ah_attr;
+       int ret;
+
+       av->port = port;
+       av->pkey_index = wc->pkey_index;
+
+       /*
+        * av->ah_attr might be initialized based on past wc during incoming
+        * connect request or while sending out connect request. So initialize
+        * a new ah_attr on stack. If initialization fails, old ah_attr is
+        * used for sending any responses. If initialization is successful,
+        * than new ah_attr is used by overwriting old one.
+        */
+       ret = ib_init_ah_attr_from_wc(port->cm_dev->ib_device,
+                                     port->port_num, wc,
+                                     grh, &new_ah_attr);
+       if (ret)
+               return ret;
+
+       memcpy(&av->ah_attr, &new_ah_attr, sizeof(new_ah_attr));
+       return 0;
+}
+
 static int cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
                                   struct ib_grh *grh, struct cm_av *av)
 {
@@ -3233,9 +3259,9 @@ static int cm_lap_handler(struct cm_work *work)
                goto unlock;
        }
 
-       ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
-                                     work->mad_recv_wc->recv_buf.grh,
-                                     &cm_id_priv->av);
+       ret = cm_init_av_for_lap(work->port, work->mad_recv_wc->wc,
+                                work->mad_recv_wc->recv_buf.grh,
+                                &cm_id_priv->av);
        if (ret)
                goto unlock;