Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e225dcb authored by Parav Pandit's avatar Parav Pandit Committed by Jason Gunthorpe
Browse files

IB/cm: Store and restore ah_attr during LAP msg processing



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: default avatarParav Pandit <parav@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent a5c57d32
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -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,7 +3259,7 @@ static int cm_lap_handler(struct cm_work *work)
		goto unlock;
	}

	ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
	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)