Skip to content

Commit 1e70094

Browse files
GuangguanWangdavem330
authored andcommitted
net/smc: support smc release version negotiation in clc handshake
Support smc release version negotiation in clc handshake based on SMC v2, where no negotiation process for different releases, but for different versions. The latest smc release version was updated to v2.1. And currently there are two release versions of SMCv2, v2.0 and v2.1. In the release version negotiation, client sends the preferred release version by CLC Proposal Message, server makes decision for which release version to use based on the client preferred release version and self-supported release version (here choose the minimum release version of the client preferred and server latest supported), then the decision returns to client by CLC Accept Message. Client confirms the decision by CLC Confirm Message. Client Server Proposal(preferred release version) ------------------------------------> Accept(accpeted release version) min(client preferred, server latest supported) <------------------------------------ Confirm(accpeted release version) ------------------------------------> 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>
1 parent cb49ec0 commit 1e70094

File tree

5 files changed

+51
-13
lines changed

5 files changed

+51
-13
lines changed

net/smc/af_smc.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,8 +1198,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
11981198
struct smc_clc_msg_accept_confirm_v2 *clc_v2 =
11991199
(struct smc_clc_msg_accept_confirm_v2 *)aclc;
12001200
struct smc_clc_first_contact_ext *fce =
1201-
(struct smc_clc_first_contact_ext *)
1202-
(((u8 *)clc_v2) + sizeof(*clc_v2));
1201+
smc_get_clc_first_contact_ext(clc_v2, false);
12031202

12041203
if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1)
12051204
return 0;
@@ -1218,6 +1217,9 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
12181217
return SMC_CLC_DECL_NOINDIRECT;
12191218
}
12201219
}
1220+
1221+
ini->release_nr = fce->release;
1222+
12211223
return 0;
12221224
}
12231225

@@ -1386,6 +1388,13 @@ static int smc_connect_ism(struct smc_sock *smc,
13861388
struct smc_clc_msg_accept_confirm_v2 *aclc_v2 =
13871389
(struct smc_clc_msg_accept_confirm_v2 *)aclc;
13881390

1391+
if (ini->first_contact_peer) {
1392+
struct smc_clc_first_contact_ext *fce =
1393+
smc_get_clc_first_contact_ext(aclc_v2, true);
1394+
1395+
ini->release_nr = fce->release;
1396+
}
1397+
13891398
rc = smc_v2_determine_accepted_chid(aclc_v2, ini);
13901399
if (rc)
13911400
return rc;
@@ -1420,7 +1429,7 @@ static int smc_connect_ism(struct smc_sock *smc,
14201429
}
14211430

14221431
rc = smc_clc_send_confirm(smc, ini->first_contact_local,
1423-
aclc->hdr.version, eid, NULL);
1432+
aclc->hdr.version, eid, ini);
14241433
if (rc)
14251434
goto connect_abort;
14261435
mutex_unlock(&smc_server_lgr_pending);
@@ -1996,6 +2005,10 @@ static int smc_listen_v2_check(struct smc_sock *new_smc,
19962005
}
19972006
}
19982007

2008+
ini->release_nr = pclc_v2_ext->hdr.flag.release;
2009+
if (pclc_v2_ext->hdr.flag.release > SMC_RELEASE)
2010+
ini->release_nr = SMC_RELEASE;
2011+
19992012
out:
20002013
if (!ini->smcd_version && !ini->smcr_version)
20012014
return rc;
@@ -2443,7 +2456,7 @@ static void smc_listen_work(struct work_struct *work)
24432456
/* send SMC Accept CLC message */
24442457
accept_version = ini->is_smcd ? ini->smcd_version : ini->smcr_version;
24452458
rc = smc_clc_send_accept(new_smc, ini->first_contact_local,
2446-
accept_version, ini->negotiated_eid);
2459+
accept_version, ini->negotiated_eid, ini);
24472460
if (rc)
24482461
goto out_unlock;
24492462

net/smc/smc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121

2222
#define SMC_V1 1 /* SMC version V1 */
2323
#define SMC_V2 2 /* SMC version V2 */
24-
#define SMC_RELEASE 0
24+
25+
#define SMC_RELEASE_0 0
26+
#define SMC_RELEASE_1 1
27+
#define SMC_RELEASE SMC_RELEASE_1 /* the latest release version */
2528

2629
#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */
2730
#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */

net/smc/smc_clc.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,11 @@ smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)
420420
return true;
421421
}
422422

423-
static void smc_clc_fill_fce(struct smc_clc_first_contact_ext *fce, int *len)
423+
static void smc_clc_fill_fce(struct smc_clc_first_contact_ext *fce, int *len, int release_nr)
424424
{
425425
memset(fce, 0, sizeof(*fce));
426426
fce->os_type = SMC_CLC_OS_LINUX;
427-
fce->release = SMC_RELEASE;
427+
fce->release = release_nr;
428428
memcpy(fce->hostname, smc_hostname, sizeof(smc_hostname));
429429
(*len) += sizeof(*fce);
430430
}
@@ -1019,7 +1019,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
10191019
memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN);
10201020
len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
10211021
if (first_contact)
1022-
smc_clc_fill_fce(&fce, &len);
1022+
smc_clc_fill_fce(&fce, &len, ini->release_nr);
10231023
clc_v2->hdr.length = htons(len);
10241024
}
10251025
memcpy(trl.eyecatcher, SMCD_EYECATCHER,
@@ -1063,10 +1063,10 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
10631063
memcpy(clc_v2->r1.eid, eid, SMC_MAX_EID_LEN);
10641064
len = SMCR_CLC_ACCEPT_CONFIRM_LEN_V2;
10651065
if (first_contact) {
1066-
smc_clc_fill_fce(&fce, &len);
1066+
smc_clc_fill_fce(&fce, &len, ini->release_nr);
10671067
fce.v2_direct = !link->lgr->uses_gateway;
10681068
memset(&gle, 0, sizeof(gle));
1069-
if (ini && clc->hdr.type == SMC_CLC_CONFIRM) {
1069+
if (clc->hdr.type == SMC_CLC_CONFIRM) {
10701070
gle.gid_cnt = ini->smcrv2.gidlist.len;
10711071
len += sizeof(gle);
10721072
len += gle.gid_cnt * sizeof(gle.gid[0]);
@@ -1141,15 +1141,15 @@ int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
11411141

11421142
/* send CLC ACCEPT message across internal TCP socket */
11431143
int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
1144-
u8 version, u8 *negotiated_eid)
1144+
u8 version, u8 *negotiated_eid, struct smc_init_info *ini)
11451145
{
11461146
struct smc_clc_msg_accept_confirm_v2 aclc_v2;
11471147
int len;
11481148

11491149
memset(&aclc_v2, 0, sizeof(aclc_v2));
11501150
aclc_v2.hdr.type = SMC_CLC_ACCEPT;
11511151
len = smc_clc_send_confirm_accept(new_smc, &aclc_v2, srv_first_contact,
1152-
version, negotiated_eid, NULL);
1152+
version, negotiated_eid, ini);
11531153
if (len < ntohs(aclc_v2.hdr.length))
11541154
len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;
11551155

net/smc/smc_clc.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,27 @@ smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext)
370370
ntohs(prop_v2ext->hdr.smcd_v2_ext_offset));
371371
}
372372

373+
static inline struct smc_clc_first_contact_ext *
374+
smc_get_clc_first_contact_ext(struct smc_clc_msg_accept_confirm_v2 *clc_v2,
375+
bool is_smcd)
376+
{
377+
int clc_v2_len;
378+
379+
if (clc_v2->hdr.version == SMC_V1 ||
380+
!(clc_v2->hdr.typev2 & SMC_FIRST_CONTACT_MASK))
381+
return NULL;
382+
383+
if (is_smcd)
384+
clc_v2_len =
385+
offsetofend(struct smc_clc_msg_accept_confirm_v2, d1);
386+
else
387+
clc_v2_len =
388+
offsetofend(struct smc_clc_msg_accept_confirm_v2, r1);
389+
390+
return (struct smc_clc_first_contact_ext *)(((u8 *)clc_v2) +
391+
clc_v2_len);
392+
}
393+
373394
struct smcd_dev;
374395
struct smc_init_info;
375396

@@ -382,7 +403,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini);
382403
int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
383404
u8 version, u8 *eid, struct smc_init_info *ini);
384405
int smc_clc_send_accept(struct smc_sock *smc, bool srv_first_contact,
385-
u8 version, u8 *negotiated_eid);
406+
u8 version, u8 *negotiated_eid, struct smc_init_info *ini);
386407
void smc_clc_init(void) __init;
387408
void smc_clc_exit(void);
388409
void smc_clc_get_hostname(u8 **host);

net/smc/smc_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ struct smc_init_info {
374374
u8 is_smcd;
375375
u8 smc_type_v1;
376376
u8 smc_type_v2;
377+
u8 release_nr;
377378
u8 first_contact_peer;
378379
u8 first_contact_local;
379380
unsigned short vlan_id;

0 commit comments

Comments
 (0)