Commit 3d9725a6 authored by Ursula Braun's avatar Ursula Braun Committed by David S. Miller

net/smc: common routine for CLC accept and confirm

smc_clc_send_accept() and smc_clc_send_confirm() are quite similar.
Move common code into a separate function smc_clc_send_confirm_accept().
And introduce separate SMCD and SMCR struct definitions for CLC accept
resp. confirm.
No functional change.
Signed-off-by: default avatarUrsula Braun <ubraun@linux.ibm.com>
Signed-off-by: default avatarKarsten Graul <kgraul@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6bb14e48
...@@ -436,10 +436,10 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc) ...@@ -436,10 +436,10 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc)
static void smcr_conn_save_peer_info(struct smc_sock *smc, static void smcr_conn_save_peer_info(struct smc_sock *smc,
struct smc_clc_msg_accept_confirm *clc) struct smc_clc_msg_accept_confirm *clc)
{ {
int bufsize = smc_uncompress_bufsize(clc->rmbe_size); int bufsize = smc_uncompress_bufsize(clc->r0.rmbe_size);
smc->conn.peer_rmbe_idx = clc->rmbe_idx; smc->conn.peer_rmbe_idx = clc->r0.rmbe_idx;
smc->conn.local_tx_ctrl.token = ntohl(clc->rmbe_alert_token); smc->conn.local_tx_ctrl.token = ntohl(clc->r0.rmbe_alert_token);
smc->conn.peer_rmbe_size = bufsize; smc->conn.peer_rmbe_size = bufsize;
atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size); atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size);
smc->conn.tx_off = bufsize * (smc->conn.peer_rmbe_idx - 1); smc->conn.tx_off = bufsize * (smc->conn.peer_rmbe_idx - 1);
...@@ -448,10 +448,10 @@ static void smcr_conn_save_peer_info(struct smc_sock *smc, ...@@ -448,10 +448,10 @@ static void smcr_conn_save_peer_info(struct smc_sock *smc,
static void smcd_conn_save_peer_info(struct smc_sock *smc, static void smcd_conn_save_peer_info(struct smc_sock *smc,
struct smc_clc_msg_accept_confirm *clc) struct smc_clc_msg_accept_confirm *clc)
{ {
int bufsize = smc_uncompress_bufsize(clc->dmbe_size); int bufsize = smc_uncompress_bufsize(clc->d0.dmbe_size);
smc->conn.peer_rmbe_idx = clc->dmbe_idx; smc->conn.peer_rmbe_idx = clc->d0.dmbe_idx;
smc->conn.peer_token = clc->token; smc->conn.peer_token = clc->d0.token;
/* msg header takes up space in the buffer */ /* msg header takes up space in the buffer */
smc->conn.peer_rmbe_size = bufsize - sizeof(struct smcd_cdc_msg); smc->conn.peer_rmbe_size = bufsize - sizeof(struct smcd_cdc_msg);
atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size); atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size);
...@@ -470,11 +470,11 @@ static void smc_conn_save_peer_info(struct smc_sock *smc, ...@@ -470,11 +470,11 @@ static void smc_conn_save_peer_info(struct smc_sock *smc,
static void smc_link_save_peer_info(struct smc_link *link, static void smc_link_save_peer_info(struct smc_link *link,
struct smc_clc_msg_accept_confirm *clc) struct smc_clc_msg_accept_confirm *clc)
{ {
link->peer_qpn = ntoh24(clc->qpn); link->peer_qpn = ntoh24(clc->r0.qpn);
memcpy(link->peer_gid, clc->lcl.gid, SMC_GID_SIZE); memcpy(link->peer_gid, clc->r0.lcl.gid, SMC_GID_SIZE);
memcpy(link->peer_mac, clc->lcl.mac, sizeof(link->peer_mac)); memcpy(link->peer_mac, clc->r0.lcl.mac, sizeof(link->peer_mac));
link->peer_psn = ntoh24(clc->psn); link->peer_psn = ntoh24(clc->r0.psn);
link->peer_mtu = clc->qp_mtu; link->peer_mtu = clc->r0.qp_mtu;
} }
static void smc_switch_to_fallback(struct smc_sock *smc) static void smc_switch_to_fallback(struct smc_sock *smc)
...@@ -613,8 +613,8 @@ static int smc_connect_rdma(struct smc_sock *smc, ...@@ -613,8 +613,8 @@ static int smc_connect_rdma(struct smc_sock *smc,
struct smc_link *link; struct smc_link *link;
ini->is_smcd = false; ini->is_smcd = false;
ini->ib_lcl = &aclc->lcl; ini->ib_lcl = &aclc->r0.lcl;
ini->ib_clcqpn = ntoh24(aclc->qpn); ini->ib_clcqpn = ntoh24(aclc->r0.qpn);
ini->first_contact_peer = aclc->hdr.flag; ini->first_contact_peer = aclc->hdr.flag;
mutex_lock(&smc_client_lgr_pending); mutex_lock(&smc_client_lgr_pending);
...@@ -634,9 +634,11 @@ static int smc_connect_rdma(struct smc_sock *smc, ...@@ -634,9 +634,11 @@ static int smc_connect_rdma(struct smc_sock *smc,
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
struct smc_link *l = &smc->conn.lgr->lnk[i]; struct smc_link *l = &smc->conn.lgr->lnk[i];
if (l->peer_qpn == ntoh24(aclc->qpn) && if (l->peer_qpn == ntoh24(aclc->r0.qpn) &&
!memcmp(l->peer_gid, &aclc->lcl.gid, SMC_GID_SIZE) && !memcmp(l->peer_gid, &aclc->r0.lcl.gid,
!memcmp(l->peer_mac, &aclc->lcl.mac, sizeof(l->peer_mac))) { SMC_GID_SIZE) &&
!memcmp(l->peer_mac, &aclc->r0.lcl.mac,
sizeof(l->peer_mac))) {
link = l; link = l;
break; break;
} }
...@@ -707,7 +709,7 @@ static int smc_connect_ism(struct smc_sock *smc, ...@@ -707,7 +709,7 @@ static int smc_connect_ism(struct smc_sock *smc,
int rc = 0; int rc = 0;
ini->is_smcd = true; ini->is_smcd = true;
ini->ism_peer_gid = aclc->gid; ini->ism_peer_gid = aclc->d0.gid;
ini->first_contact_peer = aclc->hdr.flag; ini->first_contact_peer = aclc->hdr.flag;
/* there is only one lgr role for SMC-D; use server lock */ /* there is only one lgr role for SMC-D; use server lock */
......
...@@ -497,65 +497,85 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type, ...@@ -497,65 +497,85 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
return reason_code; return reason_code;
} }
/* send CLC CONFIRM message across internal TCP socket */ /* build and send CLC CONFIRM / ACCEPT message */
int smc_clc_send_confirm(struct smc_sock *smc) static int smc_clc_send_confirm_accept(struct smc_sock *smc,
struct smc_clc_msg_accept_confirm *clc,
int first_contact)
{ {
struct smc_connection *conn = &smc->conn; struct smc_connection *conn = &smc->conn;
struct smc_clc_msg_accept_confirm cclc;
struct smc_link *link;
int reason_code = 0;
struct msghdr msg; struct msghdr msg;
struct kvec vec; struct kvec vec;
int len;
/* send SMC Confirm CLC msg */ /* send SMC Confirm CLC msg */
memset(&cclc, 0, sizeof(cclc)); clc->hdr.version = SMC_V1; /* SMC version */
cclc.hdr.type = SMC_CLC_CONFIRM; if (first_contact)
cclc.hdr.version = SMC_V1; /* SMC version */ clc->hdr.flag = 1;
if (conn->lgr->is_smcd) { if (conn->lgr->is_smcd) {
/* SMC-D specific settings */ /* SMC-D specific settings */
memcpy(cclc.hdr.eyecatcher, SMCD_EYECATCHER, memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
sizeof(SMCD_EYECATCHER)); sizeof(SMCD_EYECATCHER));
cclc.hdr.path = SMC_TYPE_D; clc->hdr.path = SMC_TYPE_D;
cclc.hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN); clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
cclc.gid = conn->lgr->smcd->local_gid; clc->d0.gid = conn->lgr->smcd->local_gid;
cclc.token = conn->rmb_desc->token; clc->d0.token = conn->rmb_desc->token;
cclc.dmbe_size = conn->rmbe_size_short; clc->d0.dmbe_size = conn->rmbe_size_short;
cclc.dmbe_idx = 0; clc->d0.dmbe_idx = 0;
memcpy(&cclc.linkid, conn->lgr->id, SMC_LGR_ID_SIZE); memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
memcpy(cclc.smcd_trl.eyecatcher, SMCD_EYECATCHER, memcpy(clc->d0.smcd_trl.eyecatcher, SMCD_EYECATCHER,
sizeof(SMCD_EYECATCHER)); sizeof(SMCD_EYECATCHER));
} else { } else {
struct smc_link *link = conn->lnk;
/* SMC-R specific settings */ /* SMC-R specific settings */
link = conn->lnk; link = conn->lnk;
memcpy(cclc.hdr.eyecatcher, SMC_EYECATCHER, memcpy(clc->hdr.eyecatcher, SMC_EYECATCHER,
sizeof(SMC_EYECATCHER)); sizeof(SMC_EYECATCHER));
cclc.hdr.path = SMC_TYPE_R; clc->hdr.path = SMC_TYPE_R;
cclc.hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN); clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
memcpy(cclc.lcl.id_for_peer, local_systemid, memcpy(clc->r0.lcl.id_for_peer, local_systemid,
sizeof(local_systemid)); sizeof(local_systemid));
memcpy(&cclc.lcl.gid, link->gid, SMC_GID_SIZE); memcpy(&clc->r0.lcl.gid, link->gid, SMC_GID_SIZE);
memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], memcpy(&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
ETH_ALEN); ETH_ALEN);
hton24(cclc.qpn, link->roce_qp->qp_num); hton24(clc->r0.qpn, link->roce_qp->qp_num);
cclc.rmb_rkey = clc->r0.rmb_rkey =
htonl(conn->rmb_desc->mr_rx[link->link_idx]->rkey); htonl(conn->rmb_desc->mr_rx[link->link_idx]->rkey);
cclc.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */ clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
cclc.rmbe_alert_token = htonl(conn->alert_token_local); clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
cclc.qp_mtu = min(link->path_mtu, link->peer_mtu); switch (clc->hdr.type) {
cclc.rmbe_size = conn->rmbe_size_short; case SMC_CLC_ACCEPT:
cclc.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address clc->r0.qp_mtu = link->path_mtu;
break;
case SMC_CLC_CONFIRM:
clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu);
break;
}
clc->r0.rmbe_size = conn->rmbe_size_short;
clc->r0.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
(conn->rmb_desc->sgt[link->link_idx].sgl)); (conn->rmb_desc->sgt[link->link_idx].sgl));
hton24(cclc.psn, link->psn_initial); hton24(clc->r0.psn, link->psn_initial);
memcpy(cclc.smcr_trl.eyecatcher, SMC_EYECATCHER, memcpy(clc->r0.smcr_trl.eyecatcher, SMC_EYECATCHER,
sizeof(SMC_EYECATCHER)); sizeof(SMC_EYECATCHER));
} }
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
vec.iov_base = &cclc; vec.iov_base = clc;
vec.iov_len = ntohs(cclc.hdr.length); vec.iov_len = ntohs(clc->hdr.length);
len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, return kernel_sendmsg(smc->clcsock, &msg, &vec, 1,
ntohs(cclc.hdr.length)); ntohs(clc->hdr.length));
}
/* send CLC CONFIRM message across internal TCP socket */
int smc_clc_send_confirm(struct smc_sock *smc)
{
struct smc_clc_msg_accept_confirm cclc;
int reason_code = 0;
int len;
/* send SMC Confirm CLC msg */
memset(&cclc, 0, sizeof(cclc));
cclc.hdr.type = SMC_CLC_CONFIRM;
len = smc_clc_send_confirm_accept(smc, &cclc, 0);
if (len < ntohs(cclc.hdr.length)) { if (len < ntohs(cclc.hdr.length)) {
if (len >= 0) { if (len >= 0) {
reason_code = -ENETUNREACH; reason_code = -ENETUNREACH;
...@@ -571,63 +591,12 @@ int smc_clc_send_confirm(struct smc_sock *smc) ...@@ -571,63 +591,12 @@ int smc_clc_send_confirm(struct smc_sock *smc)
/* send CLC ACCEPT message across internal TCP socket */ /* send CLC ACCEPT message across internal TCP socket */
int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact) int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact)
{ {
struct smc_connection *conn = &new_smc->conn;
struct smc_clc_msg_accept_confirm aclc; struct smc_clc_msg_accept_confirm aclc;
struct smc_link *link;
struct msghdr msg;
struct kvec vec;
int len; int len;
memset(&aclc, 0, sizeof(aclc)); memset(&aclc, 0, sizeof(aclc));
aclc.hdr.type = SMC_CLC_ACCEPT; aclc.hdr.type = SMC_CLC_ACCEPT;
aclc.hdr.version = SMC_V1; /* SMC version */ len = smc_clc_send_confirm_accept(new_smc, &aclc, srv_first_contact);
if (srv_first_contact)
aclc.hdr.flag = 1;
if (conn->lgr->is_smcd) {
/* SMC-D specific settings */
aclc.hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
memcpy(aclc.hdr.eyecatcher, SMCD_EYECATCHER,
sizeof(SMCD_EYECATCHER));
aclc.hdr.path = SMC_TYPE_D;
aclc.gid = conn->lgr->smcd->local_gid;
aclc.token = conn->rmb_desc->token;
aclc.dmbe_size = conn->rmbe_size_short;
aclc.dmbe_idx = 0;
memcpy(&aclc.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
memcpy(aclc.smcd_trl.eyecatcher, SMCD_EYECATCHER,
sizeof(SMCD_EYECATCHER));
} else {
/* SMC-R specific settings */
aclc.hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
memcpy(aclc.hdr.eyecatcher, SMC_EYECATCHER,
sizeof(SMC_EYECATCHER));
aclc.hdr.path = SMC_TYPE_R;
link = conn->lnk;
memcpy(aclc.lcl.id_for_peer, local_systemid,
sizeof(local_systemid));
memcpy(&aclc.lcl.gid, link->gid, SMC_GID_SIZE);
memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1],
ETH_ALEN);
hton24(aclc.qpn, link->roce_qp->qp_num);
aclc.rmb_rkey =
htonl(conn->rmb_desc->mr_rx[link->link_idx]->rkey);
aclc.rmbe_idx = 1; /* as long as 1 RMB = 1 RMBE */
aclc.rmbe_alert_token = htonl(conn->alert_token_local);
aclc.qp_mtu = link->path_mtu;
aclc.rmbe_size = conn->rmbe_size_short,
aclc.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
(conn->rmb_desc->sgt[link->link_idx].sgl));
hton24(aclc.psn, link->psn_initial);
memcpy(aclc.smcr_trl.eyecatcher, SMC_EYECATCHER,
sizeof(SMC_EYECATCHER));
}
memset(&msg, 0, sizeof(msg));
vec.iov_base = &aclc;
vec.iov_len = ntohs(aclc.hdr.length);
len = kernel_sendmsg(new_smc->clcsock, &msg, &vec, 1,
ntohs(aclc.hdr.length));
if (len < ntohs(aclc.hdr.length)) if (len < ntohs(aclc.hdr.length))
len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err; len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;
......
...@@ -118,46 +118,50 @@ struct smc_clc_msg_proposal_area { ...@@ -118,46 +118,50 @@ struct smc_clc_msg_proposal_area {
struct smc_clc_msg_trail pclc_trl; struct smc_clc_msg_trail pclc_trl;
}; };
struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */ struct smcr_clc_msg_accept_confirm { /* SMCR accept/confirm */
struct smc_clc_msg_hdr hdr; struct smc_clc_msg_local lcl;
union { u8 qpn[3]; /* QP number */
struct { /* SMC-R */ __be32 rmb_rkey; /* RMB rkey */
struct smc_clc_msg_local lcl; u8 rmbe_idx; /* Index of RMBE in RMB */
u8 qpn[3]; /* QP number */ __be32 rmbe_alert_token; /* unique connection id */
__be32 rmb_rkey; /* RMB rkey */ #if defined(__BIG_ENDIAN_BITFIELD)
u8 rmbe_idx; /* Index of RMBE in RMB */ u8 rmbe_size : 4, /* buf size (compressed) */
__be32 rmbe_alert_token;/* unique connection id */ qp_mtu : 4; /* QP mtu */
#if defined(__BIG_ENDIAN_BITFIELD)
u8 rmbe_size : 4, /* buf size (compressed) */
qp_mtu : 4; /* QP mtu */
#elif defined(__LITTLE_ENDIAN_BITFIELD) #elif defined(__LITTLE_ENDIAN_BITFIELD)
u8 qp_mtu : 4, u8 qp_mtu : 4,
rmbe_size : 4; rmbe_size : 4;
#endif #endif
u8 reserved; u8 reserved;
__be64 rmb_dma_addr; /* RMB virtual address */ __be64 rmb_dma_addr; /* RMB virtual address */
u8 reserved2; u8 reserved2;
u8 psn[3]; /* packet sequence number */ u8 psn[3]; /* packet sequence number */
struct smc_clc_msg_trail smcr_trl; struct smc_clc_msg_trail smcr_trl;
/* eye catcher "SMCR" EBCDIC */ /* eye catcher "SMCR" EBCDIC */
} __packed; } __packed;
struct { /* SMC-D */
u64 gid; /* Sender GID */ struct smcd_clc_msg_accept_confirm { /* SMCD accept/confirm */
u64 token; /* DMB token */ u64 gid; /* Sender GID */
u8 dmbe_idx; /* DMBE index */ u64 token; /* DMB token */
u8 dmbe_idx; /* DMBE index */
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
u8 dmbe_size : 4, /* buf size (compressed) */ u8 dmbe_size : 4, /* buf size (compressed) */
reserved3 : 4; reserved3 : 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD) #elif defined(__LITTLE_ENDIAN_BITFIELD)
u8 reserved3 : 4, u8 reserved3 : 4,
dmbe_size : 4; dmbe_size : 4;
#endif #endif
u16 reserved4; u16 reserved4;
u32 linkid; /* Link identifier */ u32 linkid; /* Link identifier */
u32 reserved5[3]; u32 reserved5[3];
struct smc_clc_msg_trail smcd_trl; struct smc_clc_msg_trail smcd_trl;
/* eye catcher "SMCD" EBCDIC */ /* eye catcher "SMCD" EBCDIC */
} __packed; } __packed;
struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */
struct smc_clc_msg_hdr hdr;
union {
struct smcr_clc_msg_accept_confirm r0; /* SMC-R */
struct smcd_clc_msg_accept_confirm d0; /* SMC-D */
}; };
} __packed; /* format defined in RFC7609 */ } __packed; /* format defined in RFC7609 */
......
...@@ -1892,8 +1892,8 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn, ...@@ -1892,8 +1892,8 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn,
struct smc_link *lnk, struct smc_link *lnk,
struct smc_clc_msg_accept_confirm *clc) struct smc_clc_msg_accept_confirm *clc)
{ {
conn->rtoken_idx = smc_rtoken_add(lnk, clc->rmb_dma_addr, conn->rtoken_idx = smc_rtoken_add(lnk, clc->r0.rmb_dma_addr,
clc->rmb_rkey); clc->r0.rmb_rkey);
if (conn->rtoken_idx < 0) if (conn->rtoken_idx < 0)
return conn->rtoken_idx; return conn->rtoken_idx;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment