Skip to content

Commit 42042db

Browse files
karstengrdavem330
authored andcommitted
net/smc: prepare for SMC-Rv2 connection
Prepare the connection establishment with SMC-Rv2. Detect eligible RoCE cards and indicate all supported SMC modes for the connection. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ed990df commit 42042db

File tree

4 files changed

+113
-35
lines changed

4 files changed

+113
-35
lines changed

net/smc/af_smc.c

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,9 @@ static int smc_find_rdma_device(struct smc_sock *smc, struct smc_init_info *ini)
608608
* used for the internal TCP socket
609609
*/
610610
smc_pnet_find_roce_resource(smc->clcsock->sk, ini);
611-
if (!ini->ib_dev)
611+
if (!ini->check_smcrv2 && !ini->ib_dev)
612+
return SMC_CLC_DECL_NOSMCRDEV;
613+
if (ini->check_smcrv2 && !ini->smcrv2.ib_dev_v2)
612614
return SMC_CLC_DECL_NOSMCRDEV;
613615
return 0;
614616
}
@@ -692,27 +694,42 @@ static int smc_find_proposal_devices(struct smc_sock *smc,
692694
int rc = 0;
693695

694696
/* check if there is an ism device available */
695-
if (ini->smcd_version & SMC_V1) {
696-
if (smc_find_ism_device(smc, ini) ||
697-
smc_connect_ism_vlan_setup(smc, ini)) {
698-
if (ini->smc_type_v1 == SMC_TYPE_B)
699-
ini->smc_type_v1 = SMC_TYPE_R;
700-
else
701-
ini->smc_type_v1 = SMC_TYPE_N;
702-
} /* else ISM V1 is supported for this connection */
703-
if (smc_find_rdma_device(smc, ini)) {
704-
if (ini->smc_type_v1 == SMC_TYPE_B)
705-
ini->smc_type_v1 = SMC_TYPE_D;
706-
else
707-
ini->smc_type_v1 = SMC_TYPE_N;
708-
} /* else RDMA is supported for this connection */
709-
}
710-
if (smc_ism_is_v2_capable() && smc_find_ism_v2_device_clnt(smc, ini))
711-
ini->smc_type_v2 = SMC_TYPE_N;
697+
if (!(ini->smcd_version & SMC_V1) ||
698+
smc_find_ism_device(smc, ini) ||
699+
smc_connect_ism_vlan_setup(smc, ini))
700+
ini->smcd_version &= ~SMC_V1;
701+
/* else ISM V1 is supported for this connection */
702+
703+
/* check if there is an rdma device available */
704+
if (!(ini->smcr_version & SMC_V1) ||
705+
smc_find_rdma_device(smc, ini))
706+
ini->smcr_version &= ~SMC_V1;
707+
/* else RDMA is supported for this connection */
708+
709+
ini->smc_type_v1 = smc_indicated_type(ini->smcd_version & SMC_V1,
710+
ini->smcr_version & SMC_V1);
711+
712+
/* check if there is an ism v2 device available */
713+
if (!(ini->smcd_version & SMC_V2) ||
714+
!smc_ism_is_v2_capable() ||
715+
smc_find_ism_v2_device_clnt(smc, ini))
716+
ini->smcd_version &= ~SMC_V2;
717+
718+
/* check if there is an rdma v2 device available */
719+
ini->check_smcrv2 = true;
720+
ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr;
721+
if (!(ini->smcr_version & SMC_V2) ||
722+
smc->clcsock->sk->sk_family != AF_INET ||
723+
!smc_clc_ueid_count() ||
724+
smc_find_rdma_device(smc, ini))
725+
ini->smcr_version &= ~SMC_V2;
726+
ini->check_smcrv2 = false;
727+
728+
ini->smc_type_v2 = smc_indicated_type(ini->smcd_version & SMC_V2,
729+
ini->smcr_version & SMC_V2);
712730

713731
/* if neither ISM nor RDMA are supported, fallback */
714-
if (!smcr_indicated(ini->smc_type_v1) &&
715-
ini->smc_type_v1 == SMC_TYPE_N && ini->smc_type_v2 == SMC_TYPE_N)
732+
if (ini->smc_type_v1 == SMC_TYPE_N && ini->smc_type_v2 == SMC_TYPE_N)
716733
rc = SMC_CLC_DECL_NOSMCDEV;
717734

718735
return rc;
@@ -950,17 +967,24 @@ static int smc_connect_ism(struct smc_sock *smc,
950967
static int smc_connect_check_aclc(struct smc_init_info *ini,
951968
struct smc_clc_msg_accept_confirm *aclc)
952969
{
953-
if ((aclc->hdr.typev1 == SMC_TYPE_R &&
954-
!smcr_indicated(ini->smc_type_v1)) ||
955-
(aclc->hdr.typev1 == SMC_TYPE_D &&
956-
((!smcd_indicated(ini->smc_type_v1) &&
957-
!smcd_indicated(ini->smc_type_v2)) ||
958-
(aclc->hdr.version == SMC_V1 &&
959-
!smcd_indicated(ini->smc_type_v1)) ||
960-
(aclc->hdr.version == SMC_V2 &&
961-
!smcd_indicated(ini->smc_type_v2)))))
970+
if (aclc->hdr.typev1 != SMC_TYPE_R &&
971+
aclc->hdr.typev1 != SMC_TYPE_D)
962972
return SMC_CLC_DECL_MODEUNSUPP;
963973

974+
if (aclc->hdr.version >= SMC_V2) {
975+
if ((aclc->hdr.typev1 == SMC_TYPE_R &&
976+
!smcr_indicated(ini->smc_type_v2)) ||
977+
(aclc->hdr.typev1 == SMC_TYPE_D &&
978+
!smcd_indicated(ini->smc_type_v2)))
979+
return SMC_CLC_DECL_MODEUNSUPP;
980+
} else {
981+
if ((aclc->hdr.typev1 == SMC_TYPE_R &&
982+
!smcr_indicated(ini->smc_type_v1)) ||
983+
(aclc->hdr.typev1 == SMC_TYPE_D &&
984+
!smcd_indicated(ini->smc_type_v1)))
985+
return SMC_CLC_DECL_MODEUNSUPP;
986+
}
987+
964988
return 0;
965989
}
966990

@@ -991,14 +1015,15 @@ static int __smc_connect(struct smc_sock *smc)
9911015
return smc_connect_decline_fallback(smc, SMC_CLC_DECL_MEM,
9921016
version);
9931017

994-
ini->smcd_version = SMC_V1;
995-
ini->smcd_version |= smc_ism_is_v2_capable() ? SMC_V2 : 0;
1018+
ini->smcd_version = SMC_V1 | SMC_V2;
1019+
ini->smcr_version = SMC_V1 | SMC_V2;
9961020
ini->smc_type_v1 = SMC_TYPE_B;
997-
ini->smc_type_v2 = smc_ism_is_v2_capable() ? SMC_TYPE_D : SMC_TYPE_N;
1021+
ini->smc_type_v2 = SMC_TYPE_B;
9981022

9991023
/* get vlan id from IP device */
10001024
if (smc_vlan_by_tcpsk(smc->clcsock, ini)) {
10011025
ini->smcd_version &= ~SMC_V1;
1026+
ini->smcr_version = 0;
10021027
ini->smc_type_v1 = SMC_TYPE_N;
10031028
if (!ini->smcd_version) {
10041029
rc = SMC_CLC_DECL_GETVLANERR;
@@ -1026,15 +1051,17 @@ static int __smc_connect(struct smc_sock *smc)
10261051
/* check if smc modes and versions of CLC proposal and accept match */
10271052
rc = smc_connect_check_aclc(ini, aclc);
10281053
version = aclc->hdr.version == SMC_V1 ? SMC_V1 : SMC_V2;
1029-
ini->smcd_version = version;
10301054
if (rc)
10311055
goto vlan_cleanup;
10321056

10331057
/* depending on previous steps, connect using rdma or ism */
1034-
if (aclc->hdr.typev1 == SMC_TYPE_R)
1058+
if (aclc->hdr.typev1 == SMC_TYPE_R) {
1059+
ini->smcr_version = version;
10351060
rc = smc_connect_rdma(smc, aclc, ini);
1036-
else if (aclc->hdr.typev1 == SMC_TYPE_D)
1061+
} else if (aclc->hdr.typev1 == SMC_TYPE_D) {
1062+
ini->smcd_version = version;
10371063
rc = smc_connect_ism(smc, aclc, ini);
1064+
}
10381065
if (rc)
10391066
goto vlan_cleanup;
10401067

net/smc/smc_clc.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ static int smc_clc_ueid_add(char *ueid)
114114
return rc;
115115
}
116116

117+
int smc_clc_ueid_count(void)
118+
{
119+
int count;
120+
121+
read_lock(&smc_clc_eid_table.lock);
122+
count = smc_clc_eid_table.ueid_cnt;
123+
read_unlock(&smc_clc_eid_table.lock);
124+
125+
return count;
126+
}
127+
117128
int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info)
118129
{
119130
struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];

net/smc/smc_clc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ static inline bool smcd_indicated(int smc_type)
282282
return smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B;
283283
}
284284

285+
static inline u8 smc_indicated_type(int is_smcd, int is_smcr)
286+
{
287+
if (is_smcd && is_smcr)
288+
return SMC_TYPE_B;
289+
if (is_smcd)
290+
return SMC_TYPE_D;
291+
if (is_smcr)
292+
return SMC_TYPE_R;
293+
return SMC_TYPE_N;
294+
}
295+
285296
/* get SMC-D info from proposal message */
286297
static inline struct smc_clc_msg_smcd *
287298
smc_get_clc_msg_smcd(struct smc_clc_msg_proposal *prop)
@@ -343,6 +354,7 @@ void smc_clc_get_hostname(u8 **host);
343354
bool smc_clc_match_eid(u8 *negotiated_eid,
344355
struct smc_clc_v2_extension *smc_v2_ext,
345356
u8 *peer_eid, u8 *local_eid);
357+
int smc_clc_ueid_count(void);
346358
int smc_nl_dump_ueid(struct sk_buff *skb, struct netlink_callback *cb);
347359
int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info);
348360
int smc_nl_remove_ueid(struct sk_buff *skb, struct genl_info *info);

net/smc/smc_core.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,31 @@ struct smc_link_group {
302302

303303
struct smc_clc_msg_local;
304304

305+
#define GID_LIST_SIZE 2
306+
307+
struct smc_gidlist {
308+
u8 len;
309+
u8 list[GID_LIST_SIZE][SMC_GID_SIZE];
310+
};
311+
312+
struct smc_init_info_smcrv2 {
313+
/* Input fields */
314+
__be32 saddr;
315+
struct sock *clc_sk;
316+
__be32 daddr;
317+
318+
/* Output fields when saddr is set */
319+
struct smc_ib_device *ib_dev_v2;
320+
u8 ib_port_v2;
321+
u8 ib_gid_v2[SMC_GID_SIZE];
322+
323+
/* Additional output fields when clc_sk and daddr is set as well */
324+
u8 uses_gateway;
325+
u8 nexthop_mac[ETH_ALEN];
326+
327+
struct smc_gidlist gidlist;
328+
};
329+
305330
struct smc_init_info {
306331
u8 is_smcd;
307332
u8 smc_type_v1;
@@ -313,10 +338,13 @@ struct smc_init_info {
313338
u8 negotiated_eid[SMC_MAX_EID_LEN];
314339
/* SMC-R */
315340
struct smc_clc_msg_local *ib_lcl;
341+
u8 smcr_version;
342+
u8 check_smcrv2;
316343
struct smc_ib_device *ib_dev;
317344
u8 ib_gid[SMC_GID_SIZE];
318345
u8 ib_port;
319346
u32 ib_clcqpn;
347+
struct smc_init_info_smcrv2 smcrv2;
320348
/* SMC-D */
321349
u64 ism_peer_gid[SMC_MAX_ISM_DEVS + 1];
322350
struct smcd_dev *ism_dev[SMC_MAX_ISM_DEVS + 1];

0 commit comments

Comments
 (0)