net/smc: separate find device functions
This patch provides better separation of device determinations in function smc_listen_work(). 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>
This commit is contained in:
parent
f1eb02f952
commit
7affc80982
111
net/smc/af_smc.c
111
net/smc/af_smc.c
|
@ -1188,7 +1188,6 @@ static int smc_listen_rdma_init(struct smc_sock *new_smc,
|
|||
|
||||
/* listen worker: initialize connection and buffers for SMC-D */
|
||||
static int smc_listen_ism_init(struct smc_sock *new_smc,
|
||||
struct smc_clc_msg_proposal *pclc,
|
||||
struct smc_init_info *ini)
|
||||
{
|
||||
int rc;
|
||||
|
@ -1211,6 +1210,26 @@ static int smc_listen_ism_init(struct smc_sock *new_smc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void smc_find_ism_device_serv(struct smc_sock *new_smc,
|
||||
struct smc_clc_msg_proposal *pclc,
|
||||
struct smc_init_info *ini)
|
||||
{
|
||||
struct smc_clc_msg_smcd *pclc_smcd = smc_get_clc_msg_smcd(pclc);
|
||||
|
||||
if (!smcd_indicated(pclc->hdr.typev1))
|
||||
goto not_found;
|
||||
ini->is_smcd = true; /* prepare ISM check */
|
||||
ini->ism_peer_gid = pclc_smcd->gid;
|
||||
if (smc_find_ism_device(new_smc, ini))
|
||||
goto not_found;
|
||||
if (!smc_listen_ism_init(new_smc, ini))
|
||||
return; /* ISM device found */
|
||||
|
||||
not_found:
|
||||
ini->ism_dev = NULL;
|
||||
ini->is_smcd = false;
|
||||
}
|
||||
|
||||
/* listen worker: register buffers */
|
||||
static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)
|
||||
{
|
||||
|
@ -1225,6 +1244,47 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int smc_find_rdma_device_serv(struct smc_sock *new_smc,
|
||||
struct smc_clc_msg_proposal *pclc,
|
||||
struct smc_init_info *ini)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!smcr_indicated(pclc->hdr.typev1))
|
||||
return SMC_CLC_DECL_NOSMCDEV;
|
||||
|
||||
/* prepare RDMA check */
|
||||
ini->ib_lcl = &pclc->lcl;
|
||||
rc = smc_find_rdma_device(new_smc, ini);
|
||||
if (rc) {
|
||||
/* no RDMA device found */
|
||||
if (pclc->hdr.typev1 == SMC_TYPE_B)
|
||||
/* neither ISM nor RDMA device found */
|
||||
rc = SMC_CLC_DECL_NOSMCDEV;
|
||||
return rc;
|
||||
}
|
||||
rc = smc_listen_rdma_init(new_smc, ini);
|
||||
if (rc)
|
||||
return rc;
|
||||
return smc_listen_rdma_reg(new_smc, ini->first_contact_local);
|
||||
}
|
||||
|
||||
/* determine the local device matching to proposal */
|
||||
static int smc_listen_find_device(struct smc_sock *new_smc,
|
||||
struct smc_clc_msg_proposal *pclc,
|
||||
struct smc_init_info *ini)
|
||||
{
|
||||
/* check if ISM is available */
|
||||
smc_find_ism_device_serv(new_smc, pclc, ini);
|
||||
if (ini->is_smcd)
|
||||
return 0;
|
||||
if (pclc->hdr.typev1 == SMC_TYPE_D)
|
||||
return SMC_CLC_DECL_NOSMCDDEV; /* skip RDMA and decline */
|
||||
|
||||
/* check if RDMA is available */
|
||||
return smc_find_rdma_device_serv(new_smc, pclc, ini);
|
||||
}
|
||||
|
||||
/* listen worker: finish RDMA setup */
|
||||
static int smc_listen_rdma_finish(struct smc_sock *new_smc,
|
||||
struct smc_clc_msg_accept_confirm *cclc,
|
||||
|
@ -1250,7 +1310,7 @@ static int smc_listen_rdma_finish(struct smc_sock *new_smc,
|
|||
return reason_code;
|
||||
}
|
||||
|
||||
/* setup for RDMA connection of server */
|
||||
/* setup for connection of server */
|
||||
static void smc_listen_work(struct work_struct *work)
|
||||
{
|
||||
struct smc_sock *new_smc = container_of(work, struct smc_sock,
|
||||
|
@ -1260,7 +1320,6 @@ static void smc_listen_work(struct work_struct *work)
|
|||
struct smc_clc_msg_proposal_area *buf;
|
||||
struct smc_clc_msg_proposal *pclc;
|
||||
struct smc_init_info ini = {0};
|
||||
bool ism_supported = false;
|
||||
int rc = 0;
|
||||
|
||||
if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
|
||||
|
@ -1315,42 +1374,10 @@ static void smc_listen_work(struct work_struct *work)
|
|||
smc_rx_init(new_smc);
|
||||
smc_tx_init(new_smc);
|
||||
|
||||
/* check if ISM is available */
|
||||
if (pclc->hdr.typev1 == SMC_TYPE_D || pclc->hdr.typev1 == SMC_TYPE_B) {
|
||||
struct smc_clc_msg_smcd *pclc_smcd = smc_get_clc_msg_smcd(pclc);
|
||||
|
||||
ini.is_smcd = true; /* prepare ISM check */
|
||||
ini.ism_peer_gid = pclc_smcd->gid;
|
||||
rc = smc_find_ism_device(new_smc, &ini);
|
||||
if (!rc)
|
||||
rc = smc_listen_ism_init(new_smc, pclc, &ini);
|
||||
if (!rc)
|
||||
ism_supported = true;
|
||||
else if (pclc->hdr.typev1 == SMC_TYPE_D)
|
||||
goto out_unlock; /* skip RDMA and decline */
|
||||
}
|
||||
|
||||
/* check if RDMA is available */
|
||||
if (!ism_supported) { /* SMC_TYPE_R or SMC_TYPE_B */
|
||||
/* prepare RDMA check */
|
||||
ini.is_smcd = false;
|
||||
ini.ism_dev = NULL;
|
||||
ini.ib_lcl = &pclc->lcl;
|
||||
rc = smc_find_rdma_device(new_smc, &ini);
|
||||
if (rc) {
|
||||
/* no RDMA device found */
|
||||
if (pclc->hdr.typev1 == SMC_TYPE_B)
|
||||
/* neither ISM nor RDMA device found */
|
||||
rc = SMC_CLC_DECL_NOSMCDEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
rc = smc_listen_rdma_init(new_smc, &ini);
|
||||
if (rc)
|
||||
goto out_unlock;
|
||||
rc = smc_listen_rdma_reg(new_smc, ini.first_contact_local);
|
||||
if (rc)
|
||||
goto out_unlock;
|
||||
}
|
||||
/* determine ISM or RoCE device used for connection */
|
||||
rc = smc_listen_find_device(new_smc, pclc, &ini);
|
||||
if (rc)
|
||||
goto out_unlock;
|
||||
|
||||
/* send SMC Accept CLC message */
|
||||
rc = smc_clc_send_accept(new_smc, ini.first_contact_local);
|
||||
|
@ -1358,20 +1385,20 @@ static void smc_listen_work(struct work_struct *work)
|
|||
goto out_unlock;
|
||||
|
||||
/* SMC-D does not need this lock any more */
|
||||
if (ism_supported)
|
||||
if (ini.is_smcd)
|
||||
mutex_unlock(&smc_server_lgr_pending);
|
||||
|
||||
/* receive SMC Confirm CLC message */
|
||||
rc = smc_clc_wait_msg(new_smc, &cclc, sizeof(cclc),
|
||||
SMC_CLC_CONFIRM, CLC_WAIT_TIME);
|
||||
if (rc) {
|
||||
if (!ism_supported)
|
||||
if (!ini.is_smcd)
|
||||
goto out_unlock;
|
||||
goto out_decl;
|
||||
}
|
||||
|
||||
/* finish worker */
|
||||
if (!ism_supported) {
|
||||
if (!ini.is_smcd) {
|
||||
rc = smc_listen_rdma_finish(new_smc, &cclc,
|
||||
ini.first_contact_local);
|
||||
if (rc)
|
||||
|
|
|
@ -450,7 +450,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
|
|||
pclc_base->hdr.type = SMC_CLC_PROPOSAL;
|
||||
pclc_base->hdr.version = SMC_V1; /* SMC version */
|
||||
pclc_base->hdr.typev1 = smc_type;
|
||||
if (smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B) {
|
||||
if (smcr_indicated(smc_type)) {
|
||||
/* add SMC-R specifics */
|
||||
memcpy(pclc_base->lcl.id_for_peer, local_systemid,
|
||||
sizeof(local_systemid));
|
||||
|
@ -459,7 +459,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
|
|||
ETH_ALEN);
|
||||
pclc_base->iparea_offset = htons(0);
|
||||
}
|
||||
if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B) {
|
||||
if (smcd_indicated(smc_type)) {
|
||||
/* add SMC-D specifics */
|
||||
plen += sizeof(*pclc_smcd);
|
||||
pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
|
||||
|
@ -472,7 +472,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
|
|||
i = 0;
|
||||
vec[i].iov_base = pclc_base;
|
||||
vec[i++].iov_len = sizeof(*pclc_base);
|
||||
if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B) {
|
||||
if (smcd_indicated(smc_type)) {
|
||||
vec[i].iov_base = pclc_smcd;
|
||||
vec[i++].iov_len = sizeof(*pclc_smcd);
|
||||
}
|
||||
|
|
|
@ -180,11 +180,22 @@ smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)
|
|||
((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset));
|
||||
}
|
||||
|
||||
static inline bool smcr_indicated(int smc_type)
|
||||
{
|
||||
return smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B;
|
||||
}
|
||||
|
||||
static inline bool smcd_indicated(int smc_type)
|
||||
{
|
||||
return smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B;
|
||||
}
|
||||
|
||||
/* get SMC-D info from proposal message */
|
||||
static inline struct smc_clc_msg_smcd *
|
||||
smc_get_clc_msg_smcd(struct smc_clc_msg_proposal *prop)
|
||||
{
|
||||
if (ntohs(prop->iparea_offset) != sizeof(struct smc_clc_msg_smcd))
|
||||
if (smcd_indicated(prop->hdr.type) &&
|
||||
ntohs(prop->iparea_offset) != sizeof(struct smc_clc_msg_smcd))
|
||||
return NULL;
|
||||
|
||||
return (struct smc_clc_msg_smcd *)(prop + 1);
|
||||
|
|
Loading…
Reference in a new issue