Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/cm: Use DLID from inbound/outbound PathRecords as the datapath DLID

In inter-subnet cases, when inbound/outbound PRs are available,
outbound_PR.dlid is used as the requestor's datapath DLID and
inbound_PR.dlid is used as the responder's DLID. The inbound_PR.dlid
is passed to responder side with the "ConnectReq.Primary_Local_Port_LID"
field. With this solution the PERMISSIVE_LID is no longer used in
Primary Local LID field.

Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Link: https://lore.kernel.org/r/b3f6cac685bce9dde37c610be82e2c19d9e51d9e.1662631201.git.leonro@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Mark Zhang and committed by
Leon Romanovsky
eb8336db b7d95040

+27 -2
+23 -2
drivers/infiniband/core/cm.c
··· 175 175 struct cm_av { 176 176 struct cm_port *port; 177 177 struct rdma_ah_attr ah_attr; 178 + u16 dlid_datapath; 178 179 u16 pkey_index; 179 180 u8 timeout; 180 181 }; ··· 1305 1304 struct sa_path_rec *pri_path = param->primary_path; 1306 1305 struct sa_path_rec *alt_path = param->alternate_path; 1307 1306 bool pri_ext = false; 1307 + __be16 lid; 1308 1308 1309 1309 if (pri_path->rec_type == SA_PATH_REC_TYPE_OPA) 1310 1310 pri_ext = opa_is_extended_lid(pri_path->opa.dlid, ··· 1365 1363 htons(ntohl(sa_path_get_dlid( 1366 1364 pri_path))))); 1367 1365 } else { 1366 + 1367 + if (param->primary_path_inbound) { 1368 + lid = param->primary_path_inbound->ib.dlid; 1369 + IBA_SET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg, 1370 + be16_to_cpu(lid)); 1371 + } else 1372 + IBA_SET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg, 1373 + be16_to_cpu(IB_LID_PERMISSIVE)); 1374 + 1368 1375 /* Work-around until there's a way to obtain remote LID info */ 1369 - IBA_SET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg, 1370 - be16_to_cpu(IB_LID_PERMISSIVE)); 1371 1376 IBA_SET(CM_REQ_PRIMARY_REMOTE_PORT_LID, req_msg, 1372 1377 be16_to_cpu(IB_LID_PERMISSIVE)); 1373 1378 } ··· 1529 1520 spin_lock_irqsave(&cm_id_priv->lock, flags); 1530 1521 1531 1522 cm_move_av_from_path(&cm_id_priv->av, &av); 1523 + if (param->primary_path_outbound) 1524 + cm_id_priv->av.dlid_datapath = 1525 + be16_to_cpu(param->primary_path_outbound->ib.dlid); 1526 + 1532 1527 if (param->alternate_path) 1533 1528 cm_move_av_from_path(&cm_id_priv->alt_av, &alt_av); 1534 1529 ··· 2167 2154 NULL, 0); 2168 2155 goto rejected; 2169 2156 } 2157 + if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_IB) 2158 + cm_id_priv->av.dlid_datapath = 2159 + IBA_GET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg); 2160 + 2170 2161 if (cm_req_has_alt_path(req_msg)) { 2171 2162 ret = cm_init_av_by_path(&work->path[1], NULL, 2172 2163 &cm_id_priv->alt_av); ··· 4130 4113 *qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU | 4131 4114 IB_QP_DEST_QPN | IB_QP_RQ_PSN; 4132 4115 qp_attr->ah_attr = cm_id_priv->av.ah_attr; 4116 + if ((qp_attr->ah_attr.type == RDMA_AH_ATTR_TYPE_IB) && 4117 + cm_id_priv->av.dlid_datapath && 4118 + (cm_id_priv->av.dlid_datapath != 0xffff)) 4119 + qp_attr->ah_attr.ib.dlid = cm_id_priv->av.dlid_datapath; 4133 4120 qp_attr->path_mtu = cm_id_priv->path_mtu; 4134 4121 qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn); 4135 4122 qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn);
+2
drivers/infiniband/core/cma.c
··· 4313 4313 } 4314 4314 4315 4315 req.primary_path = &route->path_rec[0]; 4316 + req.primary_path_inbound = route->path_rec_inbound; 4317 + req.primary_path_outbound = route->path_rec_outbound; 4316 4318 if (route->num_pri_alt_paths == 2) 4317 4319 req.alternate_path = &route->path_rec[1]; 4318 4320
+2
include/rdma/ib_cm.h
··· 348 348 349 349 struct ib_cm_req_param { 350 350 struct sa_path_rec *primary_path; 351 + struct sa_path_rec *primary_path_inbound; 352 + struct sa_path_rec *primary_path_outbound; 351 353 struct sa_path_rec *alternate_path; 352 354 const struct ib_gid_attr *ppath_sgid_attr; 353 355 __be64 service_id;