aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cm.c
diff options
context:
space:
mode:
authorParav Pandit <parav@mellanox.com>2018-05-14 11:11:09 +0300
committerJason Gunthorpe <jgg@mellanox.com>2018-05-16 14:11:46 -0600
commite822ff213fe60dc539a7e2137a08b04004f8ec25 (patch)
tree11742b699931a9832cbb896dc1a67f892b2758b9 /drivers/infiniband/core/cm.c
parentIB/cm: Store and restore ah_attr during LAP msg processing (diff)
downloadlinux-dev-e822ff213fe60dc539a7e2137a08b04004f8ec25.tar.xz
linux-dev-e822ff213fe60dc539a7e2137a08b04004f8ec25.zip
IB/cm: Store and restore ah_attr during CM message processing
During CM request processing flow, ah_attr is initialized twice. First based on wc. Secondly based on primary path record. ah_attr initialization from path record can fail, which leads to ah_attr zeroed out. Therefore, always initialize ah_attr on stack during reinitialization phase. If ah_attr init is successful, use the new ah_attry by overwriting the old one. If the ah_attr init fails, continue to use the last ah_attr. Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core/cm.c')
-rw-r--r--drivers/infiniband/core/cm.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 8b640cb88f3a..7df4c7173607 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -535,6 +535,7 @@ static struct cm_port *get_cm_port_from_path(struct sa_path_rec *path)
static int cm_init_av_by_path(struct sa_path_rec *path, struct cm_av *av,
struct cm_id_private *cm_id_priv)
{
+ struct rdma_ah_attr new_ah_attr;
struct cm_device *cm_dev;
struct cm_port *port;
int ret;
@@ -550,15 +551,26 @@ static int cm_init_av_by_path(struct sa_path_rec *path, struct cm_av *av,
return ret;
av->port = port;
+
+ /*
+ * av->ah_attr might be initialized based on wc or during
+ * request processing time. 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 the old one.
+ */
ret = ib_init_ah_attr_from_path(cm_dev->ib_device, port->port_num, path,
- &av->ah_attr);
+ &new_ah_attr);
if (ret)
return ret;
av->timeout = path->packet_life_time + 1;
ret = add_cm_id_to_port_list(cm_id_priv, av, port);
- return ret;
+ if (ret)
+ return ret;
+ memcpy(&av->ah_attr, &new_ah_attr, sizeof(new_ah_attr));
+ return 0;
}
static int cm_alloc_id(struct cm_id_private *cm_id_priv)