Skip to content

Commit c758dfd

Browse files
Hans Wippeldavem330
authored andcommitted
net/smc: add SMC-D support in CLC messages
There are two types of SMC: SMC-R and SMC-D. These types are signaled within the CLC messages during the CLC handshake. This patch adds support for and checks of the SMC type. Also, SMC-R and SMC-D need to exchange different information during the CLC handshake. So, this patch extends the current message formats to support the SMC-D header fields. The Proposal message can contain both SMC-R and SMC-D information. The Accept and Confirm messages contain either SMC-R or SMC-D information. Signed-off-by: Hans Wippel <[email protected]> Signed-off-by: Ursula Braun <[email protected]> Suggested-by: Thomas Richter <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1619f77 commit c758dfd

File tree

3 files changed

+205
-78
lines changed

3 files changed

+205
-78
lines changed

net/smc/af_smc.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,14 +451,14 @@ static int smc_check_rdma(struct smc_sock *smc, struct smc_ib_device **ibdev,
451451
}
452452

453453
/* CLC handshake during connect */
454-
static int smc_connect_clc(struct smc_sock *smc,
454+
static int smc_connect_clc(struct smc_sock *smc, int smc_type,
455455
struct smc_clc_msg_accept_confirm *aclc,
456456
struct smc_ib_device *ibdev, u8 ibport)
457457
{
458458
int rc = 0;
459459

460460
/* do inband token exchange */
461-
rc = smc_clc_send_proposal(smc, ibdev, ibport);
461+
rc = smc_clc_send_proposal(smc, smc_type, ibdev, ibport, NULL);
462462
if (rc)
463463
return rc;
464464
/* receive SMC Accept CLC message */
@@ -564,7 +564,7 @@ static int __smc_connect(struct smc_sock *smc)
564564
return smc_connect_decline_fallback(smc, SMC_CLC_DECL_CNFERR);
565565

566566
/* perform CLC handshake */
567-
rc = smc_connect_clc(smc, &aclc, ibdev, ibport);
567+
rc = smc_connect_clc(smc, SMC_TYPE_R, &aclc, ibdev, ibport);
568568
if (rc)
569569
return smc_connect_decline_fallback(smc, rc);
570570

@@ -1008,7 +1008,8 @@ static void smc_listen_work(struct work_struct *work)
10081008
smc_tx_init(new_smc);
10091009

10101010
/* check if RDMA is available */
1011-
if (smc_check_rdma(new_smc, &ibdev, &ibport) ||
1011+
if ((pclc->hdr.path != SMC_TYPE_R && pclc->hdr.path != SMC_TYPE_B) ||
1012+
smc_check_rdma(new_smc, &ibdev, &ibport) ||
10121013
smc_listen_rdma_check(new_smc, pclc) ||
10131014
smc_listen_rdma_init(new_smc, pclc, ibdev, ibport,
10141015
&local_contact) ||

net/smc/smc_clc.c

Lines changed: 137 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@
2323
#include "smc_core.h"
2424
#include "smc_clc.h"
2525
#include "smc_ib.h"
26+
#include "smc_ism.h"
27+
28+
#define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
29+
#define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
2630

2731
/* eye catcher "SMCR" EBCDIC for CLC messages */
2832
static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
33+
/* eye catcher "SMCD" EBCDIC for CLC messages */
34+
static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};
2935

3036
/* check if received message has a correct header length and contains valid
3137
* heading and trailing eyecatchers
@@ -38,10 +44,14 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
3844
struct smc_clc_msg_decline *dclc;
3945
struct smc_clc_msg_trail *trl;
4046

41-
if (memcmp(clcm->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)))
47+
if (memcmp(clcm->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
48+
memcmp(clcm->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
4249
return false;
4350
switch (clcm->type) {
4451
case SMC_CLC_PROPOSAL:
52+
if (clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D &&
53+
clcm->path != SMC_TYPE_B)
54+
return false;
4555
pclc = (struct smc_clc_msg_proposal *)clcm;
4656
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
4757
if (ntohs(pclc->hdr.length) !=
@@ -56,10 +66,16 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
5666
break;
5767
case SMC_CLC_ACCEPT:
5868
case SMC_CLC_CONFIRM:
69+
if (clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D)
70+
return false;
5971
clc = (struct smc_clc_msg_accept_confirm *)clcm;
60-
if (ntohs(clc->hdr.length) != sizeof(*clc))
72+
if ((clcm->path == SMC_TYPE_R &&
73+
ntohs(clc->hdr.length) != SMCR_CLC_ACCEPT_CONFIRM_LEN) ||
74+
(clcm->path == SMC_TYPE_D &&
75+
ntohs(clc->hdr.length) != SMCD_CLC_ACCEPT_CONFIRM_LEN))
6176
return false;
62-
trl = &clc->trl;
77+
trl = (struct smc_clc_msg_trail *)
78+
((u8 *)clc + ntohs(clc->hdr.length) - sizeof(*trl));
6379
break;
6480
case SMC_CLC_DECLINE:
6581
dclc = (struct smc_clc_msg_decline *)clcm;
@@ -70,7 +86,8 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
7086
default:
7187
return false;
7288
}
73-
if (memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)))
89+
if (memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
90+
memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
7491
return false;
7592
return true;
7693
}
@@ -295,6 +312,9 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
295312
datlen = ntohs(clcm->length);
296313
if ((len < sizeof(struct smc_clc_msg_hdr)) ||
297314
(datlen > buflen) ||
315+
(clcm->version != SMC_CLC_V1) ||
316+
(clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D &&
317+
clcm->path != SMC_TYPE_B) ||
298318
((clcm->type != SMC_CLC_DECLINE) &&
299319
(clcm->type != expected_type))) {
300320
smc->sk.sk_err = EPROTO;
@@ -356,17 +376,18 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info)
356376
}
357377

358378
/* send CLC PROPOSAL message across internal TCP socket */
359-
int smc_clc_send_proposal(struct smc_sock *smc,
360-
struct smc_ib_device *smcibdev,
361-
u8 ibport)
379+
int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
380+
struct smc_ib_device *ibdev, u8 ibport,
381+
struct smcd_dev *ismdev)
362382
{
363383
struct smc_clc_ipv6_prefix ipv6_prfx[SMC_CLC_MAX_V6_PREFIX];
364384
struct smc_clc_msg_proposal_prefix pclc_prfx;
385+
struct smc_clc_msg_smcd pclc_smcd;
365386
struct smc_clc_msg_proposal pclc;
366387
struct smc_clc_msg_trail trl;
367388
int len, i, plen, rc;
368389
int reason_code = 0;
369-
struct kvec vec[4];
390+
struct kvec vec[5];
370391
struct msghdr msg;
371392

372393
/* retrieve ip prefixes for CLC proposal msg */
@@ -381,18 +402,34 @@ int smc_clc_send_proposal(struct smc_sock *smc,
381402
memset(&pclc, 0, sizeof(pclc));
382403
memcpy(pclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
383404
pclc.hdr.type = SMC_CLC_PROPOSAL;
384-
pclc.hdr.length = htons(plen);
385405
pclc.hdr.version = SMC_CLC_V1; /* SMC version */
386-
memcpy(pclc.lcl.id_for_peer, local_systemid, sizeof(local_systemid));
387-
memcpy(&pclc.lcl.gid, &smcibdev->gid[ibport - 1], SMC_GID_SIZE);
388-
memcpy(&pclc.lcl.mac, &smcibdev->mac[ibport - 1], ETH_ALEN);
389-
pclc.iparea_offset = htons(0);
406+
pclc.hdr.path = smc_type;
407+
if (smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B) {
408+
/* add SMC-R specifics */
409+
memcpy(pclc.lcl.id_for_peer, local_systemid,
410+
sizeof(local_systemid));
411+
memcpy(&pclc.lcl.gid, &ibdev->gid[ibport - 1], SMC_GID_SIZE);
412+
memcpy(&pclc.lcl.mac, &ibdev->mac[ibport - 1], ETH_ALEN);
413+
pclc.iparea_offset = htons(0);
414+
}
415+
if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B) {
416+
/* add SMC-D specifics */
417+
memset(&pclc_smcd, 0, sizeof(pclc_smcd));
418+
plen += sizeof(pclc_smcd);
419+
pclc.iparea_offset = htons(SMC_CLC_PROPOSAL_MAX_OFFSET);
420+
pclc_smcd.gid = ismdev->local_gid;
421+
}
422+
pclc.hdr.length = htons(plen);
390423

391424
memcpy(trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
392425
memset(&msg, 0, sizeof(msg));
393426
i = 0;
394427
vec[i].iov_base = &pclc;
395428
vec[i++].iov_len = sizeof(pclc);
429+
if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B) {
430+
vec[i].iov_base = &pclc_smcd;
431+
vec[i++].iov_len = sizeof(pclc_smcd);
432+
}
396433
vec[i].iov_base = &pclc_prfx;
397434
vec[i++].iov_len = sizeof(pclc_prfx);
398435
if (pclc_prfx.ipv6_prefixes_cnt > 0) {
@@ -428,35 +465,56 @@ int smc_clc_send_confirm(struct smc_sock *smc)
428465
struct kvec vec;
429466
int len;
430467

431-
link = &conn->lgr->lnk[SMC_SINGLE_LINK];
432468
/* send SMC Confirm CLC msg */
433469
memset(&cclc, 0, sizeof(cclc));
434-
memcpy(cclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
435470
cclc.hdr.type = SMC_CLC_CONFIRM;
436-
cclc.hdr.length = htons(sizeof(cclc));
437471
cclc.hdr.version = SMC_CLC_V1; /* SMC version */
438-
memcpy(cclc.lcl.id_for_peer, local_systemid, sizeof(local_systemid));
439-
memcpy(&cclc.lcl.gid, &link->smcibdev->gid[link->ibport - 1],
440-
SMC_GID_SIZE);
441-
memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
442-
hton24(cclc.qpn, link->roce_qp->qp_num);
443-
cclc.rmb_rkey =
444-
htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
445-
cclc.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
446-
cclc.rmbe_alert_token = htonl(conn->alert_token_local);
447-
cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
448-
cclc.rmbe_size = conn->rmbe_size_short;
449-
cclc.rmb_dma_addr = cpu_to_be64(
450-
(u64)sg_dma_address(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
451-
hton24(cclc.psn, link->psn_initial);
452-
453-
memcpy(cclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
472+
if (smc->conn.lgr->is_smcd) {
473+
/* SMC-D specific settings */
474+
memcpy(cclc.hdr.eyecatcher, SMCD_EYECATCHER,
475+
sizeof(SMCD_EYECATCHER));
476+
cclc.hdr.path = SMC_TYPE_D;
477+
cclc.hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
478+
cclc.gid = conn->lgr->smcd->local_gid;
479+
cclc.token = conn->rmb_desc->token;
480+
cclc.dmbe_size = conn->rmbe_size_short;
481+
cclc.dmbe_idx = 0;
482+
memcpy(&cclc.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
483+
memcpy(cclc.smcd_trl.eyecatcher, SMCD_EYECATCHER,
484+
sizeof(SMCD_EYECATCHER));
485+
} else {
486+
/* SMC-R specific settings */
487+
link = &conn->lgr->lnk[SMC_SINGLE_LINK];
488+
memcpy(cclc.hdr.eyecatcher, SMC_EYECATCHER,
489+
sizeof(SMC_EYECATCHER));
490+
cclc.hdr.path = SMC_TYPE_R;
491+
cclc.hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
492+
memcpy(cclc.lcl.id_for_peer, local_systemid,
493+
sizeof(local_systemid));
494+
memcpy(&cclc.lcl.gid, &link->smcibdev->gid[link->ibport - 1],
495+
SMC_GID_SIZE);
496+
memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
497+
ETH_ALEN);
498+
hton24(cclc.qpn, link->roce_qp->qp_num);
499+
cclc.rmb_rkey =
500+
htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
501+
cclc.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
502+
cclc.rmbe_alert_token = htonl(conn->alert_token_local);
503+
cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
504+
cclc.rmbe_size = conn->rmbe_size_short;
505+
cclc.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
506+
(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
507+
hton24(cclc.psn, link->psn_initial);
508+
memcpy(cclc.smcr_trl.eyecatcher, SMC_EYECATCHER,
509+
sizeof(SMC_EYECATCHER));
510+
}
454511

455512
memset(&msg, 0, sizeof(msg));
456513
vec.iov_base = &cclc;
457-
vec.iov_len = sizeof(cclc);
458-
len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, sizeof(cclc));
459-
if (len < sizeof(cclc)) {
514+
vec.iov_len = ntohs(cclc.hdr.length);
515+
len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1,
516+
ntohs(cclc.hdr.length));
517+
if (len < ntohs(cclc.hdr.length)) {
460518
if (len >= 0) {
461519
reason_code = -ENETUNREACH;
462520
smc->sk.sk_err = -reason_code;
@@ -479,35 +537,58 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact)
479537
int rc = 0;
480538
int len;
481539

482-
link = &conn->lgr->lnk[SMC_SINGLE_LINK];
483540
memset(&aclc, 0, sizeof(aclc));
484-
memcpy(aclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
485541
aclc.hdr.type = SMC_CLC_ACCEPT;
486-
aclc.hdr.length = htons(sizeof(aclc));
487542
aclc.hdr.version = SMC_CLC_V1; /* SMC version */
488543
if (srv_first_contact)
489544
aclc.hdr.flag = 1;
490-
memcpy(aclc.lcl.id_for_peer, local_systemid, sizeof(local_systemid));
491-
memcpy(&aclc.lcl.gid, &link->smcibdev->gid[link->ibport - 1],
492-
SMC_GID_SIZE);
493-
memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
494-
hton24(aclc.qpn, link->roce_qp->qp_num);
495-
aclc.rmb_rkey =
496-
htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
497-
aclc.rmbe_idx = 1; /* as long as 1 RMB = 1 RMBE */
498-
aclc.rmbe_alert_token = htonl(conn->alert_token_local);
499-
aclc.qp_mtu = link->path_mtu;
500-
aclc.rmbe_size = conn->rmbe_size_short,
501-
aclc.rmb_dma_addr = cpu_to_be64(
502-
(u64)sg_dma_address(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
503-
hton24(aclc.psn, link->psn_initial);
504-
memcpy(aclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
545+
546+
if (new_smc->conn.lgr->is_smcd) {
547+
/* SMC-D specific settings */
548+
aclc.hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
549+
memcpy(aclc.hdr.eyecatcher, SMCD_EYECATCHER,
550+
sizeof(SMCD_EYECATCHER));
551+
aclc.hdr.path = SMC_TYPE_D;
552+
aclc.gid = conn->lgr->smcd->local_gid;
553+
aclc.token = conn->rmb_desc->token;
554+
aclc.dmbe_size = conn->rmbe_size_short;
555+
aclc.dmbe_idx = 0;
556+
memcpy(&aclc.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
557+
memcpy(aclc.smcd_trl.eyecatcher, SMCD_EYECATCHER,
558+
sizeof(SMCD_EYECATCHER));
559+
} else {
560+
/* SMC-R specific settings */
561+
aclc.hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
562+
memcpy(aclc.hdr.eyecatcher, SMC_EYECATCHER,
563+
sizeof(SMC_EYECATCHER));
564+
aclc.hdr.path = SMC_TYPE_R;
565+
link = &conn->lgr->lnk[SMC_SINGLE_LINK];
566+
memcpy(aclc.lcl.id_for_peer, local_systemid,
567+
sizeof(local_systemid));
568+
memcpy(&aclc.lcl.gid, &link->smcibdev->gid[link->ibport - 1],
569+
SMC_GID_SIZE);
570+
memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1],
571+
ETH_ALEN);
572+
hton24(aclc.qpn, link->roce_qp->qp_num);
573+
aclc.rmb_rkey =
574+
htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
575+
aclc.rmbe_idx = 1; /* as long as 1 RMB = 1 RMBE */
576+
aclc.rmbe_alert_token = htonl(conn->alert_token_local);
577+
aclc.qp_mtu = link->path_mtu;
578+
aclc.rmbe_size = conn->rmbe_size_short,
579+
aclc.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
580+
(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
581+
hton24(aclc.psn, link->psn_initial);
582+
memcpy(aclc.smcr_trl.eyecatcher, SMC_EYECATCHER,
583+
sizeof(SMC_EYECATCHER));
584+
}
505585

506586
memset(&msg, 0, sizeof(msg));
507587
vec.iov_base = &aclc;
508-
vec.iov_len = sizeof(aclc);
509-
len = kernel_sendmsg(new_smc->clcsock, &msg, &vec, 1, sizeof(aclc));
510-
if (len < sizeof(aclc)) {
588+
vec.iov_len = ntohs(aclc.hdr.length);
589+
len = kernel_sendmsg(new_smc->clcsock, &msg, &vec, 1,
590+
ntohs(aclc.hdr.length));
591+
if (len < ntohs(aclc.hdr.length)) {
511592
if (len >= 0)
512593
new_smc->sk.sk_err = EPROTO;
513594
else

0 commit comments

Comments
 (0)