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

net/smc: support max links per lgr negotiation in clc handshake

Support max links per lgr negotiation in clc handshake for SMCR v2.1,
which is one of smc v2.1 features. Server makes decision for the final
value of max links based on the client preferred max links and
self-preferred max links. Here use the minimum value of the client
preferred max links and server preferred max links.

Client Server
Proposal(max links(client preferred))
-------------------------------------->

Accept(max links(accepted value))
accepted value=min(client preferred, server preferred)
<-------------------------------------

Confirm(max links(accepted value))
------------------------------------->

Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Reviewed-by: Jan Karcher <jaka@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Guangguan Wang and committed by
David S. Miller
69b888e3 7f0620b9

+81 -23
+26 -16
net/smc/af_smc.c
··· 641 641 smc_llc_link_active(link); 642 642 smcr_lgr_set_type(link->lgr, SMC_LGR_SINGLE); 643 643 644 - /* optional 2nd link, receive ADD LINK request from server */ 645 - qentry = smc_llc_wait(link->lgr, NULL, SMC_LLC_WAIT_TIME, 646 - SMC_LLC_ADD_LINK); 647 - if (!qentry) { 648 - struct smc_clc_msg_decline dclc; 644 + if (link->lgr->max_links > 1) { 645 + /* optional 2nd link, receive ADD LINK request from server */ 646 + qentry = smc_llc_wait(link->lgr, NULL, SMC_LLC_WAIT_TIME, 647 + SMC_LLC_ADD_LINK); 648 + if (!qentry) { 649 + struct smc_clc_msg_decline dclc; 649 650 650 - rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc), 651 - SMC_CLC_DECLINE, CLC_WAIT_TIME_SHORT); 652 - if (rc == -EAGAIN) 653 - rc = 0; /* no DECLINE received, go with one link */ 654 - return rc; 651 + rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc), 652 + SMC_CLC_DECLINE, CLC_WAIT_TIME_SHORT); 653 + if (rc == -EAGAIN) 654 + rc = 0; /* no DECLINE received, go with one link */ 655 + return rc; 656 + } 657 + smc_llc_flow_qentry_clr(&link->lgr->llc_flow_lcl); 658 + smc_llc_cli_add_link(link, qentry); 655 659 } 656 - smc_llc_flow_qentry_clr(&link->lgr->llc_flow_lcl); 657 - smc_llc_cli_add_link(link, qentry); 658 660 return 0; 659 661 } 660 662 ··· 1245 1243 memcpy(ini->peer_gid, aclc->r0.lcl.gid, SMC_GID_SIZE); 1246 1244 memcpy(ini->peer_mac, aclc->r0.lcl.mac, ETH_ALEN); 1247 1245 ini->max_conns = SMC_CONN_PER_LGR_MAX; 1246 + ini->max_links = SMC_LINKS_ADD_LNK_MAX; 1248 1247 1249 1248 reason_code = smc_connect_rdma_v2_prepare(smc, aclc, ini); 1250 1249 if (reason_code) ··· 1890 1887 smc_llc_link_active(link); 1891 1888 smcr_lgr_set_type(link->lgr, SMC_LGR_SINGLE); 1892 1889 1893 - down_write(&link->lgr->llc_conf_mutex); 1894 - /* initial contact - try to establish second link */ 1895 - smc_llc_srv_add_link(link, NULL); 1896 - up_write(&link->lgr->llc_conf_mutex); 1890 + if (link->lgr->max_links > 1) { 1891 + down_write(&link->lgr->llc_conf_mutex); 1892 + /* initial contact - try to establish second link */ 1893 + smc_llc_srv_add_link(link, NULL); 1894 + up_write(&link->lgr->llc_conf_mutex); 1895 + } 1897 1896 return 0; 1898 1897 } 1899 1898 ··· 2498 2493 goto out_unlock; 2499 2494 goto out_decl; 2500 2495 } 2496 + 2497 + /* fce smc release version is needed in smc_listen_rdma_finish, 2498 + * so save fce info here. 2499 + */ 2500 + smc_conn_save_peer_info_fce(new_smc, cclc); 2501 2501 2502 2502 /* finish worker */ 2503 2503 if (!ini->is_smcd) {
+16 -1
net/smc/smc_clc.c
··· 433 433 } 434 434 435 435 if (ini->release_nr >= SMC_RELEASE_1) { 436 - if (!ini->is_smcd) 436 + if (!ini->is_smcd) { 437 437 fce->max_conns = ini->max_conns; 438 + fce->max_links = ini->max_links; 439 + } 438 440 } 439 441 440 442 out: ··· 944 942 if (smcr_indicated(ini->smc_type_v2)) { 945 943 memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE); 946 944 v2_ext->max_conns = SMC_CONN_PER_LGR_PREFER; 945 + v2_ext->max_links = SMC_LINKS_PER_LGR_MAX_PREFER; 947 946 } 948 947 949 948 pclc_base->hdr.length = htons(plen); ··· 1177 1174 struct smc_clc_v2_extension *pclc_v2_ext; 1178 1175 1179 1176 ini->max_conns = SMC_CONN_PER_LGR_MAX; 1177 + ini->max_links = SMC_LINKS_ADD_LNK_MAX; 1180 1178 1181 1179 if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) || 1182 1180 ini->release_nr < SMC_RELEASE_1) ··· 1191 1187 ini->max_conns = min_t(u8, pclc_v2_ext->max_conns, SMC_CONN_PER_LGR_PREFER); 1192 1188 if (ini->max_conns < SMC_CONN_PER_LGR_MIN) 1193 1189 return SMC_CLC_DECL_MAXCONNERR; 1190 + 1191 + ini->max_links = min_t(u8, pclc_v2_ext->max_links, SMC_LINKS_PER_LGR_MAX_PREFER); 1192 + if (ini->max_links < SMC_LINKS_ADD_LNK_MIN) 1193 + return SMC_CLC_DECL_MAXLINKERR; 1194 1194 } 1195 1195 1196 1196 return 0; ··· 1213 1205 if (fce_v2x->max_conns < SMC_CONN_PER_LGR_MIN) 1214 1206 return SMC_CLC_DECL_MAXCONNERR; 1215 1207 ini->max_conns = fce_v2x->max_conns; 1208 + 1209 + if (fce_v2x->max_links > SMC_LINKS_ADD_LNK_MAX || 1210 + fce_v2x->max_links < SMC_LINKS_ADD_LNK_MIN) 1211 + return SMC_CLC_DECL_MAXLINKERR; 1212 + ini->max_links = fce_v2x->max_links; 1216 1213 } 1217 1214 1218 1215 return 0; ··· 1246 1233 if (!ini->is_smcd) { 1247 1234 if (fce_v2x->max_conns != ini->max_conns) 1248 1235 return SMC_CLC_DECL_MAXCONNERR; 1236 + if (fce_v2x->max_links != ini->max_links) 1237 + return SMC_CLC_DECL_MAXLINKERR; 1249 1238 } 1250 1239 1251 1240 return 0;
+5 -2
net/smc/smc_clc.h
··· 47 47 #define SMC_CLC_DECL_NOUEID 0x03030008 /* peer sent no UEID */ 48 48 #define SMC_CLC_DECL_RELEASEERR 0x03030009 /* release version negotiate failed */ 49 49 #define SMC_CLC_DECL_MAXCONNERR 0x0303000a /* max connections negotiate failed */ 50 + #define SMC_CLC_DECL_MAXLINKERR 0x0303000b /* max links negotiate failed */ 50 51 #define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/ 51 52 #define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */ 52 53 #define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */ ··· 137 136 struct smc_clnt_opts_area_hdr hdr; 138 137 u8 roce[16]; /* RoCEv2 GID */ 139 138 u8 max_conns; 140 - u8 reserved[15]; 139 + u8 max_links; 140 + u8 reserved[14]; 141 141 u8 user_eids[][SMC_MAX_EID_LEN]; 142 142 }; 143 143 ··· 241 239 struct smc_clc_first_contact_ext_v2x { 242 240 struct smc_clc_first_contact_ext fce_v2_base; 243 241 u8 max_conns; /* for SMC-R only */ 244 - u8 reserved3[3]; 242 + u8 max_links; /* for SMC-R only */ 243 + u8 reserved3[2]; 245 244 __be32 vendor_exp_options; 246 245 u8 reserved4[8]; 247 246 } __packed; /* format defined in
+5
net/smc/smc_core.c
··· 896 896 memcpy(lgr->nexthop_mac, ini->smcrv2.nexthop_mac, 897 897 ETH_ALEN); 898 898 lgr->max_conns = ini->max_conns; 899 + lgr->max_links = ini->max_links; 899 900 } else { 900 901 ibdev = ini->ib_dev; 901 902 ibport = ini->ib_port; 902 903 lgr->max_conns = SMC_CONN_PER_LGR_MAX; 904 + lgr->max_links = SMC_LINKS_ADD_LNK_MAX; 903 905 } 904 906 memcpy(lgr->pnet_id, ibdev->pnetid[ibport - 1], 905 907 SMC_MAX_PNETID_LEN); ··· 1666 1664 lgr->type == SMC_LGR_SYMMETRIC || 1667 1665 lgr->type == SMC_LGR_ASYMMETRIC_PEER || 1668 1666 !rdma_dev_access_netns(smcibdev->ibdev, lgr->net)) 1667 + continue; 1668 + 1669 + if (lgr->type == SMC_LGR_SINGLE && lgr->max_links <= 1) 1669 1670 continue; 1670 1671 1671 1672 /* trigger local add link processing */
+12
net/smc/smc_core.h
··· 173 173 */ 174 174 #define SMC_LINKS_PER_LGR_MAX 3 175 175 #define SMC_SINGLE_LINK 0 176 + #define SMC_LINKS_ADD_LNK_MIN 1 /* min. # of links per link group */ 177 + #define SMC_LINKS_ADD_LNK_MAX 2 /* max. # of links per link group, also is the 178 + * default value for smc-r v1.0 and v2.0 179 + */ 180 + #define SMC_LINKS_PER_LGR_MAX_PREFER 2 /* Preferred max links per link group used for 181 + * SMC-R v2.1 and later negotiation, vendors or 182 + * distrubutions may modify it to a value between 183 + * 1-2 as needed. 184 + */ 176 185 177 186 /* tx/rx buffer list element for sndbufs list and rmbs list of a lgr */ 178 187 struct smc_buf_desc { ··· 351 342 struct net *net; 352 343 u8 max_conns; 353 344 /* max conn can be assigned to lgr */ 345 + u8 max_links; 346 + /* max links can be added in lgr */ 354 347 }; 355 348 struct { /* SMC-D */ 356 349 u64 peer_gid; ··· 398 387 u8 smc_type_v2; 399 388 u8 release_nr; 400 389 u8 max_conns; 390 + u8 max_links; 401 391 u8 first_contact_peer; 402 392 u8 first_contact_local; 403 393 unsigned short vlan_id;
+17 -4
net/smc/smc_llc.c
··· 59 59 #define SMC_LLC_FLAG_ADD_LNK_REJ 0x40 60 60 #define SMC_LLC_REJ_RSN_NO_ALT_PATH 1 61 61 62 - #define SMC_LLC_ADD_LNK_MAX_LINKS 2 63 - 64 62 struct smc_llc_msg_add_link { /* type 0x02 */ 65 63 struct smc_llc_hdr hd; 66 64 u8 sender_mac[ETH_ALEN]; ··· 470 472 hton24(confllc->sender_qp_num, link->roce_qp->qp_num); 471 473 confllc->link_num = link->link_id; 472 474 memcpy(confllc->link_uid, link->link_uid, SMC_LGR_ID_SIZE); 473 - confllc->max_links = SMC_LLC_ADD_LNK_MAX_LINKS; 475 + confllc->max_links = SMC_LINKS_ADD_LNK_MAX; 474 476 if (link->lgr->smc_version == SMC_V2 && 475 - link->lgr->peer_smc_release >= SMC_RELEASE_1) 477 + link->lgr->peer_smc_release >= SMC_RELEASE_1) { 476 478 confllc->max_conns = link->lgr->max_conns; 479 + confllc->max_links = link->lgr->max_links; 480 + } 477 481 /* send llc message */ 478 482 rc = smc_wr_tx_send(link, pend); 479 483 put_out: ··· 1045 1045 goto out_reject; 1046 1046 } 1047 1047 1048 + if (lgr->type == SMC_LGR_SINGLE && lgr->max_links <= 1) { 1049 + rc = 0; 1050 + goto out_reject; 1051 + } 1052 + 1048 1053 ini->vlan_id = lgr->vlan_id; 1049 1054 if (lgr->smc_version == SMC_V2) { 1050 1055 ini->check_smcrv2 = true; ··· 1172 1167 1173 1168 if (lgr->type == SMC_LGR_SYMMETRIC || 1174 1169 lgr->type == SMC_LGR_ASYMMETRIC_PEER) 1170 + goto out; 1171 + 1172 + if (lgr->type == SMC_LGR_SINGLE && lgr->max_links <= 1) 1175 1173 goto out; 1176 1174 1177 1175 ini = kzalloc(sizeof(*ini), GFP_KERNEL); ··· 1419 1411 ini = kzalloc(sizeof(*ini), GFP_KERNEL); 1420 1412 if (!ini) { 1421 1413 rc = -ENOMEM; 1414 + goto out; 1415 + } 1416 + 1417 + if (lgr->type == SMC_LGR_SINGLE && lgr->max_links <= 1) { 1418 + rc = 0; 1422 1419 goto out; 1423 1420 } 1424 1421