aboutsummaryrefslogtreecommitdiff
path: root/sys/ofed
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2021-06-16 13:01:35 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2021-07-26 16:04:29 +0000
commitb3f8942c1a5de03ebed6ff5065e7e84d167f9523 (patch)
tree5f32eff9395d6992fd1bae7ffefec533b6943e44 /sys/ofed
parentbc73c139f027c01990a6132212117158a232bbcc (diff)
downloadsrc-b3f8942c1a5de03ebed6ff5065e7e84d167f9523.tar.gz
src-b3f8942c1a5de03ebed6ff5065e7e84d167f9523.zip
ibcore: Store and restore ah_attr during LAP msg processing.
During CM LAP processing, ah_attr is reinitialized on receiving a LAP request. First likely during CM request processing. ah_attr might get zeroed out if LAP processing fails. Therefore, try to create a 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. Linux commit: 0e225dcb7681c0a8e52fb9dc68bd8ab973de4ca2 Reviewed by: kib Sponsored by: Mellanox Technologies // NVIDIA Networking (cherry picked from commit bf5075e41e6a29232a1c5aef07e69b9173494187)
Diffstat (limited to 'sys/ofed')
-rw-r--r--sys/ofed/drivers/infiniband/core/ib_cm.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/sys/ofed/drivers/infiniband/core/ib_cm.c b/sys/ofed/drivers/infiniband/core/ib_cm.c
index c0ee472c01a1..a0bfa1cd41b4 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cm.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cm.c
@@ -460,6 +460,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 ib_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_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)
{
@@ -3253,9 +3279,9 @@ static int cm_sidr_req_handler(struct cm_work *work)
wc = work->mad_recv_wc->wc;
cm_id_priv->av.dgid.global.subnet_prefix = cpu_to_be64(wc->slid);
cm_id_priv->av.dgid.global.interface_id = 0;
- 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 out;
cm_id_priv->id.remote_id = sidr_req_msg->request_id;