net/smc: common routine for CLC accept and confirm
authorUrsula Braun <ubraun@linux.ibm.com>
Thu, 10 Sep 2020 16:48:23 +0000 (18:48 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 Sep 2020 22:24:26 +0000 (15:24 -0700)
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: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/af_smc.c
net/smc/smc_clc.c
net/smc/smc_clc.h
net/smc/smc_core.c

index 00e2a4c..fa97144 100644 (file)
@@ -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,
                                     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.local_tx_ctrl.token = ntohl(clc->rmbe_alert_token);
+       smc->conn.peer_rmbe_idx = clc->r0.rmbe_idx;
+       smc->conn.local_tx_ctrl.token = ntohl(clc->r0.rmbe_alert_token);
        smc->conn.peer_rmbe_size = bufsize;
        atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size);
        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,
 static void smcd_conn_save_peer_info(struct smc_sock *smc,
                                     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_token = clc->token;
+       smc->conn.peer_rmbe_idx = clc->d0.dmbe_idx;
+       smc->conn.peer_token = clc->d0.token;
        /* msg header takes up space in the buffer */
        smc->conn.peer_rmbe_size = bufsize - sizeof(struct smcd_cdc_msg);
        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,
 static void smc_link_save_peer_info(struct smc_link *link,
                                    struct smc_clc_msg_accept_confirm *clc)
 {
-       link->peer_qpn = ntoh24(clc->qpn);
-       memcpy(link->peer_gid, clc->lcl.gid, SMC_GID_SIZE);
-       memcpy(link->peer_mac, clc->lcl.mac, sizeof(link->peer_mac));
-       link->peer_psn = ntoh24(clc->psn);
-       link->peer_mtu = clc->qp_mtu;
+       link->peer_qpn = ntoh24(clc->r0.qpn);
+       memcpy(link->peer_gid, clc->r0.lcl.gid, SMC_GID_SIZE);
+       memcpy(link->peer_mac, clc->r0.lcl.mac, sizeof(link->peer_mac));
+       link->peer_psn = ntoh24(clc->r0.psn);
+       link->peer_mtu = clc->r0.qp_mtu;
 }
 
 static void smc_switch_to_fallback(struct smc_sock *smc)
@@ -613,8 +613,8 @@ static int smc_connect_rdma(struct smc_sock *smc,
        struct smc_link *link;
 
        ini->is_smcd = false;
-       ini->ib_lcl = &aclc->lcl;
-       ini->ib_clcqpn = ntoh24(aclc->qpn);
+       ini->ib_lcl = &aclc->r0.lcl;
+       ini->ib_clcqpn = ntoh24(aclc->r0.qpn);
        ini->first_contact_peer = aclc->hdr.flag;
 
        mutex_lock(&smc_client_lgr_pending);
@@ -634,9 +634,11 @@ static int smc_connect_rdma(struct smc_sock *smc,
                for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
                        struct smc_link *l = &smc->conn.lgr->lnk[i];
 
-                       if (l->peer_qpn == ntoh24(aclc->qpn) &&
-                           !memcmp(l->peer_gid, &aclc->lcl.gid, SMC_GID_SIZE) &&
-                           !memcmp(l->peer_mac, &aclc->lcl.mac, sizeof(l->peer_mac))) {
+                       if (l->peer_qpn == ntoh24(aclc->r0.qpn) &&
+                           !memcmp(l->peer_gid, &aclc->r0.lcl.gid,
+                                   SMC_GID_SIZE) &&
+                           !memcmp(l->peer_mac, &aclc->r0.lcl.mac,
+                                   sizeof(l->peer_mac))) {
                                link = l;
                                break;
                        }
@@ -707,7 +709,7 @@ static int smc_connect_ism(struct smc_sock *smc,
        int rc = 0;
 
        ini->is_smcd = true;
-       ini->ism_peer_gid = aclc->gid;
+       ini->ism_peer_gid = aclc->d0.gid;
        ini->first_contact_peer = aclc->hdr.flag;
 
        /* there is only one lgr role for SMC-D; use server lock */
index 0c8e74f..bd116e1 100644 (file)
@@ -497,65 +497,85 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
        return reason_code;
 }
 
-/* send CLC CONFIRM message across internal TCP socket */
-int smc_clc_send_confirm(struct smc_sock *smc)
+/* build and send CLC CONFIRM / ACCEPT message */
+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_clc_msg_accept_confirm cclc;
-       struct smc_link *link;
-       int reason_code = 0;
        struct msghdr msg;
        struct kvec vec;
-       int len;
 
        /* send SMC Confirm CLC msg */
-       memset(&cclc, 0, sizeof(cclc));
-       cclc.hdr.type = SMC_CLC_CONFIRM;
-       cclc.hdr.version = SMC_V1;              /* SMC version */
+       clc->hdr.version = SMC_V1;              /* SMC version */
+       if (first_contact)
+               clc->hdr.flag = 1;
        if (conn->lgr->is_smcd) {
                /* SMC-D specific settings */
-               memcpy(cclc.hdr.eyecatcher, SMCD_EYECATCHER,
+               memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
                       sizeof(SMCD_EYECATCHER));
-               cclc.hdr.path = SMC_TYPE_D;
-               cclc.hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
-               cclc.gid = conn->lgr->smcd->local_gid;
-               cclc.token = conn->rmb_desc->token;
-               cclc.dmbe_size = conn->rmbe_size_short;
-               cclc.dmbe_idx = 0;
-               memcpy(&cclc.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
-               memcpy(cclc.smcd_trl.eyecatcher, SMCD_EYECATCHER,
+               clc->hdr.path = SMC_TYPE_D;
+               clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
+               clc->d0.gid = conn->lgr->smcd->local_gid;
+               clc->d0.token = conn->rmb_desc->token;
+               clc->d0.dmbe_size = conn->rmbe_size_short;
+               clc->d0.dmbe_idx = 0;
+               memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
+               memcpy(clc->d0.smcd_trl.eyecatcher, SMCD_EYECATCHER,
                       sizeof(SMCD_EYECATCHER));
        } else {
+               struct smc_link *link = conn->lnk;
+
                /* SMC-R specific settings */
                link = conn->lnk;
-               memcpy(cclc.hdr.eyecatcher, SMC_EYECATCHER,
+               memcpy(clc->hdr.eyecatcher, SMC_EYECATCHER,
                       sizeof(SMC_EYECATCHER));
-               cclc.hdr.path = SMC_TYPE_R;
-               cclc.hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
-               memcpy(cclc.lcl.id_for_peer, local_systemid,
+               clc->hdr.path = SMC_TYPE_R;
+               clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
+               memcpy(clc->r0.lcl.id_for_peer, local_systemid,
                       sizeof(local_systemid));
-               memcpy(&cclc.lcl.gid, link->gid, SMC_GID_SIZE);
-               memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
+               memcpy(&clc->r0.lcl.gid, link->gid, SMC_GID_SIZE);
+               memcpy(&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
                       ETH_ALEN);
-               hton24(cclc.qpn, link->roce_qp->qp_num);
-               cclc.rmb_rkey =
+               hton24(clc->r0.qpn, link->roce_qp->qp_num);
+               clc->r0.rmb_rkey =
                        htonl(conn->rmb_desc->mr_rx[link->link_idx]->rkey);
-               cclc.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
-               cclc.rmbe_alert_token = htonl(conn->alert_token_local);
-               cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
-               cclc.rmbe_size = conn->rmbe_size_short;
-               cclc.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
+               clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
+               clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
+               switch (clc->hdr.type) {
+               case SMC_CLC_ACCEPT:
+                       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));
-               hton24(cclc.psn, link->psn_initial);
-               memcpy(cclc.smcr_trl.eyecatcher, SMC_EYECATCHER,
+               hton24(clc->r0.psn, link->psn_initial);
+               memcpy(clc->r0.smcr_trl.eyecatcher, SMC_EYECATCHER,
                       sizeof(SMC_EYECATCHER));
        }
 
        memset(&msg, 0, sizeof(msg));
-       vec.iov_base = &cclc;
-       vec.iov_len = ntohs(cclc.hdr.length);
-       len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1,
-                            ntohs(cclc.hdr.length));
+       vec.iov_base = clc;
+       vec.iov_len = ntohs(clc->hdr.length);
+       return kernel_sendmsg(smc->clcsock, &msg, &vec, 1,
+                             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 >= 0) {
                        reason_code = -ENETUNREACH;
@@ -571,63 +591,12 @@ int smc_clc_send_confirm(struct smc_sock *smc)
 /* send CLC ACCEPT message across internal TCP socket */
 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_link *link;
-       struct msghdr msg;
-       struct kvec vec;
        int len;
 
        memset(&aclc, 0, sizeof(aclc));
        aclc.hdr.type = SMC_CLC_ACCEPT;
-       aclc.hdr.version = SMC_V1;              /* SMC version */
-       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));
+       len = smc_clc_send_confirm_accept(new_smc, &aclc, srv_first_contact);
        if (len < ntohs(aclc.hdr.length))
                len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;
 
index 7f7c55f..fda474e 100644 (file)
@@ -118,46 +118,50 @@ struct smc_clc_msg_proposal_area {
        struct smc_clc_msg_trail                pclc_trl;
 };
 
-struct smc_clc_msg_accept_confirm {    /* clc accept / confirm message */
-       struct smc_clc_msg_hdr hdr;
-       union {
-               struct { /* SMC-R */
-                       struct smc_clc_msg_local lcl;
-                       u8 qpn[3];              /* QP number */
-                       __be32 rmb_rkey;        /* RMB rkey */
-                       u8 rmbe_idx;            /* Index of RMBE in RMB */
-                       __be32 rmbe_alert_token;/* unique connection id */
-#if defined(__BIG_ENDIAN_BITFIELD)
-                       u8 rmbe_size : 4,       /* buf size (compressed) */
-                          qp_mtu   : 4;        /* QP mtu */
+struct smcr_clc_msg_accept_confirm {   /* SMCR accept/confirm */
+       struct smc_clc_msg_local lcl;
+       u8 qpn[3];                      /* QP number */
+       __be32 rmb_rkey;                /* RMB rkey */
+       u8 rmbe_idx;                    /* Index of RMBE in RMB */
+       __be32 rmbe_alert_token;        /* unique connection id */
+ #if defined(__BIG_ENDIAN_BITFIELD)
+       u8 rmbe_size : 4,               /* buf size (compressed) */
+          qp_mtu   : 4;                /* QP mtu */
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
-                       u8 qp_mtu   : 4,
-                          rmbe_size : 4;
+       u8 qp_mtu   : 4,
+          rmbe_size : 4;
 #endif
-                       u8 reserved;
-                       __be64 rmb_dma_addr;    /* RMB virtual address */
-                       u8 reserved2;
-                       u8 psn[3];              /* packet sequence number */
-                       struct smc_clc_msg_trail smcr_trl;
-                                               /* eye catcher "SMCR" EBCDIC */
-               } __packed;
-               struct { /* SMC-D */
-                       u64 gid;                /* Sender GID */
-                       u64 token;              /* DMB token */
-                       u8 dmbe_idx;            /* DMBE index */
+       u8 reserved;
+       __be64 rmb_dma_addr;    /* RMB virtual address */
+       u8 reserved2;
+       u8 psn[3];              /* packet sequence number */
+       struct smc_clc_msg_trail smcr_trl;
+                               /* eye catcher "SMCR" EBCDIC */
+} __packed;
+
+struct smcd_clc_msg_accept_confirm {   /* SMCD accept/confirm */
+       u64 gid;                /* Sender GID */
+       u64 token;              /* DMB token */
+       u8 dmbe_idx;            /* DMBE index */
 #if defined(__BIG_ENDIAN_BITFIELD)
-                       u8 dmbe_size : 4,       /* buf size (compressed) */
-                          reserved3 : 4;
+       u8 dmbe_size : 4,       /* buf size (compressed) */
+          reserved3 : 4;
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
-                       u8 reserved3 : 4,
-                          dmbe_size : 4;
+       u8 reserved3 : 4,
+          dmbe_size : 4;
 #endif
-                       u16 reserved4;
-                       u32 linkid;             /* Link identifier */
-                       u32 reserved5[3];
-                       struct smc_clc_msg_trail smcd_trl;
-                                               /* eye catcher "SMCD" EBCDIC */
-               } __packed;
+       u16 reserved4;
+       u32 linkid;             /* Link identifier */
+       u32 reserved5[3];
+       struct smc_clc_msg_trail smcd_trl;
+                               /* eye catcher "SMCD" EBCDIC */
+} __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 */
 
index c02e580..0c6dfca 100644 (file)
@@ -1892,8 +1892,8 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn,
                            struct smc_link *lnk,
                            struct smc_clc_msg_accept_confirm *clc)
 {
-       conn->rtoken_idx = smc_rtoken_add(lnk, clc->rmb_dma_addr,
-                                         clc->rmb_rkey);
+       conn->rtoken_idx = smc_rtoken_add(lnk, clc->r0.rmb_dma_addr,
+                                         clc->r0.rmb_rkey);
        if (conn->rtoken_idx < 0)
                return conn->rtoken_idx;
        return 0;