Skip to content

Commit

Permalink
Merge branch 'smc-features'
Browse files Browse the repository at this point in the history
Guangguan Wang says:

====================
net/smc: several features's implementation for smc v2.1

This patch set implement several new features in SMC v2.1(https://
www.ibm.com/support/pages/node/7009315), including vendor unique
experimental options, max connections per lgr negotiation, max links
per lgr negotiation.

v1 - v2:
 - rename field fce_v20 to fce_v2_base in struct
   smc_clc_first_contact_ext_v2x
 - use smc_get_clc_first_contact_ext in smc_connect
   _rdma_v2_prepare
 - adding comment about field vendor_oui in struct
   smc_clc_msg_smcd
 - remove comment about SMC_CONN_PER_LGR_MAX in smc_
   clc_srv_v2x_features_validate
 - rename smc_clc_clnt_v2x_features_validate

RFC v2 - v1:
 - more description in commit message
 - modify SMC_CONN_PER_LGR_xxx and SMC_LINKS_ADD_LNK_xxx
   macro defination and usage
 - rename field release_ver to release_nr
 - remove redundant release version check in client
 - explicitly set the rc value in smc_llc_cli/srv_add_link

RFC v1 - RFC v2:
 - Remove ini pointer NULL check and fix code style in
   smc_clc_send_confirm_accept.
 - Optimize the max_conns check in smc_clc_xxx_v2x_features_validate.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 19, 2023
2 parents cb49ec0 + bbed596 commit 5b0a141
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 57 deletions.
2 changes: 2 additions & 0 deletions include/uapi/linux/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ enum {
enum {
SMC_NLA_LGR_R_V2_UNSPEC,
SMC_NLA_LGR_R_V2_DIRECT, /* u8 */
SMC_NLA_LGR_R_V2_MAX_CONNS, /* u8 */
SMC_NLA_LGR_R_V2_MAX_LINKS, /* u8 */
__SMC_NLA_LGR_R_V2_MAX,
SMC_NLA_LGR_R_V2_MAX = __SMC_NLA_LGR_R_V2_MAX - 1
};
Expand Down
86 changes: 64 additions & 22 deletions net/smc/af_smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,20 +641,22 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc)
smc_llc_link_active(link);
smcr_lgr_set_type(link->lgr, SMC_LGR_SINGLE);

/* optional 2nd link, receive ADD LINK request from server */
qentry = smc_llc_wait(link->lgr, NULL, SMC_LLC_WAIT_TIME,
SMC_LLC_ADD_LINK);
if (!qentry) {
struct smc_clc_msg_decline dclc;

rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
SMC_CLC_DECLINE, CLC_WAIT_TIME_SHORT);
if (rc == -EAGAIN)
rc = 0; /* no DECLINE received, go with one link */
return rc;
if (link->lgr->max_links > 1) {
/* optional 2nd link, receive ADD LINK request from server */
qentry = smc_llc_wait(link->lgr, NULL, SMC_LLC_WAIT_TIME,
SMC_LLC_ADD_LINK);
if (!qentry) {
struct smc_clc_msg_decline dclc;

rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
SMC_CLC_DECLINE, CLC_WAIT_TIME_SHORT);
if (rc == -EAGAIN)
rc = 0; /* no DECLINE received, go with one link */
return rc;
}
smc_llc_flow_qentry_clr(&link->lgr->llc_flow_lcl);
smc_llc_cli_add_link(link, qentry);
}
smc_llc_flow_qentry_clr(&link->lgr->llc_flow_lcl);
smc_llc_cli_add_link(link, qentry);
return 0;
}

Expand Down Expand Up @@ -1144,7 +1146,7 @@ static int smc_connect_ism_vlan_cleanup(struct smc_sock *smc,

#define SMC_CLC_MAX_ACCEPT_LEN \
(sizeof(struct smc_clc_msg_accept_confirm_v2) + \
sizeof(struct smc_clc_first_contact_ext) + \
sizeof(struct smc_clc_first_contact_ext_v2x) + \
sizeof(struct smc_clc_msg_trail))

/* CLC handshake during connect */
Expand Down Expand Up @@ -1198,8 +1200,8 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
struct smc_clc_msg_accept_confirm_v2 *clc_v2 =
(struct smc_clc_msg_accept_confirm_v2 *)aclc;
struct smc_clc_first_contact_ext *fce =
(struct smc_clc_first_contact_ext *)
(((u8 *)clc_v2) + sizeof(*clc_v2));
smc_get_clc_first_contact_ext(clc_v2, false);
int rc;

if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1)
return 0;
Expand All @@ -1218,6 +1220,12 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
return SMC_CLC_DECL_NOINDIRECT;
}
}

ini->release_nr = fce->release;
rc = smc_clc_clnt_v2x_features_validate(fce, ini);
if (rc)
return rc;

return 0;
}

Expand All @@ -1236,6 +1244,8 @@ static int smc_connect_rdma(struct smc_sock *smc,
memcpy(ini->peer_systemid, aclc->r0.lcl.id_for_peer, SMC_SYSTEMID_LEN);
memcpy(ini->peer_gid, aclc->r0.lcl.gid, SMC_GID_SIZE);
memcpy(ini->peer_mac, aclc->r0.lcl.mac, ETH_ALEN);
ini->max_conns = SMC_CONN_PER_LGR_MAX;
ini->max_links = SMC_LINKS_ADD_LNK_MAX;

reason_code = smc_connect_rdma_v2_prepare(smc, aclc, ini);
if (reason_code)
Expand Down Expand Up @@ -1386,6 +1396,16 @@ static int smc_connect_ism(struct smc_sock *smc,
struct smc_clc_msg_accept_confirm_v2 *aclc_v2 =
(struct smc_clc_msg_accept_confirm_v2 *)aclc;

if (ini->first_contact_peer) {
struct smc_clc_first_contact_ext *fce =
smc_get_clc_first_contact_ext(aclc_v2, true);

ini->release_nr = fce->release;
rc = smc_clc_clnt_v2x_features_validate(fce, ini);
if (rc)
return rc;
}

rc = smc_v2_determine_accepted_chid(aclc_v2, ini);
if (rc)
return rc;
Expand Down Expand Up @@ -1420,7 +1440,7 @@ static int smc_connect_ism(struct smc_sock *smc,
}

rc = smc_clc_send_confirm(smc, ini->first_contact_local,
aclc->hdr.version, eid, NULL);
aclc->hdr.version, eid, ini);
if (rc)
goto connect_abort;
mutex_unlock(&smc_server_lgr_pending);
Expand Down Expand Up @@ -1870,10 +1890,12 @@ static int smcr_serv_conf_first_link(struct smc_sock *smc)
smc_llc_link_active(link);
smcr_lgr_set_type(link->lgr, SMC_LGR_SINGLE);

down_write(&link->lgr->llc_conf_mutex);
/* initial contact - try to establish second link */
smc_llc_srv_add_link(link, NULL);
up_write(&link->lgr->llc_conf_mutex);
if (link->lgr->max_links > 1) {
down_write(&link->lgr->llc_conf_mutex);
/* initial contact - try to establish second link */
smc_llc_srv_add_link(link, NULL);
up_write(&link->lgr->llc_conf_mutex);
}
return 0;
}

Expand Down Expand Up @@ -1996,6 +2018,10 @@ static int smc_listen_v2_check(struct smc_sock *new_smc,
}
}

ini->release_nr = pclc_v2_ext->hdr.flag.release;
if (pclc_v2_ext->hdr.flag.release > SMC_RELEASE)
ini->release_nr = SMC_RELEASE;

out:
if (!ini->smcd_version && !ini->smcr_version)
return rc;
Expand Down Expand Up @@ -2430,6 +2456,10 @@ static void smc_listen_work(struct work_struct *work)
if (rc)
goto out_decl;

rc = smc_clc_srv_v2x_features_validate(pclc, ini);
if (rc)
goto out_decl;

mutex_lock(&smc_server_lgr_pending);
smc_close_init(new_smc);
smc_rx_init(new_smc);
Expand All @@ -2443,7 +2473,7 @@ static void smc_listen_work(struct work_struct *work)
/* send SMC Accept CLC message */
accept_version = ini->is_smcd ? ini->smcd_version : ini->smcr_version;
rc = smc_clc_send_accept(new_smc, ini->first_contact_local,
accept_version, ini->negotiated_eid);
accept_version, ini->negotiated_eid, ini);
if (rc)
goto out_unlock;

Expand All @@ -2462,6 +2492,18 @@ static void smc_listen_work(struct work_struct *work)
goto out_decl;
}

rc = smc_clc_v2x_features_confirm_check(cclc, ini);
if (rc) {
if (!ini->is_smcd)
goto out_unlock;
goto out_decl;
}

/* fce smc release version is needed in smc_listen_rdma_finish,
* so save fce info here.
*/
smc_conn_save_peer_info_fce(new_smc, cclc);

/* finish worker */
if (!ini->is_smcd) {
rc = smc_listen_rdma_finish(new_smc, cclc,
Expand Down
5 changes: 4 additions & 1 deletion net/smc/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@

#define SMC_V1 1 /* SMC version V1 */
#define SMC_V2 2 /* SMC version V2 */
#define SMC_RELEASE 0

#define SMC_RELEASE_0 0
#define SMC_RELEASE_1 1
#define SMC_RELEASE SMC_RELEASE_1 /* the latest release version */

#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */
#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */
Expand Down
Loading

0 comments on commit 5b0a141

Please sign in to comment.