{
/* Find ISM device with same PNETID as connecting interface */
smc_pnet_find_ism_resource(smc->clcsock->sk, ini);
- if (!ini->ism_dev)
+ if (!ini->ism_dev[0])
return SMC_CLC_DECL_NOSMCDDEV;
return 0;
}
static int smc_connect_ism_vlan_setup(struct smc_sock *smc,
struct smc_init_info *ini)
{
- if (ini->vlan_id && smc_ism_get_vlan(ini->ism_dev, ini->vlan_id))
+ if (ini->vlan_id && smc_ism_get_vlan(ini->ism_dev[0], ini->vlan_id))
return SMC_CLC_DECL_ISMVLANERR;
return 0;
}
{
if (!is_smcd)
return 0;
- if (ini->vlan_id && smc_ism_put_vlan(ini->ism_dev, ini->vlan_id))
+ if (ini->vlan_id && smc_ism_put_vlan(ini->ism_dev[0], ini->vlan_id))
return SMC_CLC_DECL_CNFERR;
return 0;
}
int rc = 0;
ini->is_smcd = true;
- ini->ism_peer_gid = aclc->d0.gid;
+ ini->ism_peer_gid[0] = aclc->d0.gid;
ini->first_contact_peer = aclc->hdr.typev2 & SMC_FIRST_CONTACT_MASK;
/* there is only one lgr role for SMC-D; use server lock */
{
bool ism_supported = false, rdma_supported = false;
struct smc_clc_msg_accept_confirm aclc;
- struct smc_init_info ini = {0};
+ struct smc_init_info *ini = NULL;
int smc_type;
int rc = 0;
if (using_ipsec(smc))
return smc_connect_decline_fallback(smc, SMC_CLC_DECL_IPSEC);
+ ini = kzalloc(sizeof(*ini), GFP_KERNEL);
+ if (!ini)
+ return smc_connect_decline_fallback(smc, SMC_CLC_DECL_MEM);
+
/* get vlan id from IP device */
- if (smc_vlan_by_tcpsk(smc->clcsock, &ini))
+ if (smc_vlan_by_tcpsk(smc->clcsock, ini)) {
+ kfree(ini);
return smc_connect_decline_fallback(smc,
SMC_CLC_DECL_GETVLANERR);
+ }
/* check if there is an ism device available */
- if (!smc_find_ism_device(smc, &ini) &&
- !smc_connect_ism_vlan_setup(smc, &ini)) {
+ if (!smc_find_ism_device(smc, ini) &&
+ !smc_connect_ism_vlan_setup(smc, ini)) {
/* ISM is supported for this connection */
ism_supported = true;
smc_type = SMC_TYPE_D;
}
/* check if there is a rdma device available */
- if (!smc_find_rdma_device(smc, &ini)) {
+ if (!smc_find_rdma_device(smc, ini)) {
/* RDMA is supported for this connection */
rdma_supported = true;
if (ism_supported)
}
/* if neither ISM nor RDMA are supported, fallback */
- if (!rdma_supported && !ism_supported)
+ if (!rdma_supported && !ism_supported) {
+ kfree(ini);
return smc_connect_decline_fallback(smc, SMC_CLC_DECL_NOSMCDEV);
+ }
/* perform CLC handshake */
- rc = smc_connect_clc(smc, smc_type, &aclc, &ini);
+ rc = smc_connect_clc(smc, smc_type, &aclc, ini);
if (rc) {
- smc_connect_ism_vlan_cleanup(smc, ism_supported, &ini);
+ smc_connect_ism_vlan_cleanup(smc, ism_supported, ini);
+ kfree(ini);
return smc_connect_decline_fallback(smc, rc);
}
/* depending on previous steps, connect using rdma or ism */
if (rdma_supported && aclc.hdr.typev1 == SMC_TYPE_R)
- rc = smc_connect_rdma(smc, &aclc, &ini);
+ rc = smc_connect_rdma(smc, &aclc, ini);
else if (ism_supported && aclc.hdr.typev1 == SMC_TYPE_D)
- rc = smc_connect_ism(smc, &aclc, &ini);
+ rc = smc_connect_ism(smc, &aclc, ini);
else
rc = SMC_CLC_DECL_MODEUNSUPP;
if (rc) {
- smc_connect_ism_vlan_cleanup(smc, ism_supported, &ini);
+ smc_connect_ism_vlan_cleanup(smc, ism_supported, ini);
+ kfree(ini);
return smc_connect_decline_fallback(smc, rc);
}
- smc_connect_ism_vlan_cleanup(smc, ism_supported, &ini);
+ smc_connect_ism_vlan_cleanup(smc, ism_supported, ini);
+ kfree(ini);
return 0;
}
if (!smcd_indicated(pclc->hdr.typev1))
goto not_found;
ini->is_smcd = true; /* prepare ISM check */
- ini->ism_peer_gid = pclc_smcd->gid;
+ ini->ism_peer_gid[0] = 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->ism_dev[0] = NULL;
ini->is_smcd = false;
}
struct smc_clc_msg_accept_confirm cclc;
struct smc_clc_msg_proposal_area *buf;
struct smc_clc_msg_proposal *pclc;
- struct smc_init_info ini = {0};
+ struct smc_init_info *ini = NULL;
int rc = 0;
if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
if (rc)
goto out_decl;
+ ini = kzalloc(sizeof(*ini), GFP_KERNEL);
+ if (!ini) {
+ rc = SMC_CLC_DECL_MEM;
+ goto out_decl;
+ }
+
/* get vlan id from IP device */
- if (smc_vlan_by_tcpsk(new_smc->clcsock, &ini)) {
+ if (smc_vlan_by_tcpsk(new_smc->clcsock, ini)) {
rc = SMC_CLC_DECL_GETVLANERR;
goto out_decl;
}
smc_tx_init(new_smc);
/* determine ISM or RoCE device used for connection */
- rc = smc_listen_find_device(new_smc, pclc, &ini);
+ 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);
+ rc = smc_clc_send_accept(new_smc, ini->first_contact_local);
if (rc)
goto out_unlock;
/* SMC-D does not need this lock any more */
- if (ini.is_smcd)
+ 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 (!ini.is_smcd)
+ if (!ini->is_smcd)
goto out_unlock;
goto out_decl;
}
/* finish worker */
- if (!ini.is_smcd) {
+ if (!ini->is_smcd) {
rc = smc_listen_rdma_finish(new_smc, &cclc,
- ini.first_contact_local);
+ ini->first_contact_local);
if (rc)
goto out_unlock;
mutex_unlock(&smc_server_lgr_pending);
out_unlock:
mutex_unlock(&smc_server_lgr_pending);
out_decl:
- smc_listen_decline(new_smc, rc, ini.first_contact_local);
+ smc_listen_decline(new_smc, rc, ini ? ini->first_contact_local : 0);
out_free:
+ kfree(ini);
kfree(buf);
}
int i;
if (ini->is_smcd && ini->vlan_id) {
- if (smc_ism_get_vlan(ini->ism_dev, ini->vlan_id)) {
+ if (smc_ism_get_vlan(ini->ism_dev[0], ini->vlan_id)) {
rc = SMC_CLC_DECL_ISMVLANERR;
goto out;
}
lgr->conns_all = RB_ROOT;
if (ini->is_smcd) {
/* SMC-D specific settings */
- get_device(&ini->ism_dev->dev);
- lgr->peer_gid = ini->ism_peer_gid;
- lgr->smcd = ini->ism_dev;
- lgr_list = &ini->ism_dev->lgr_list;
+ get_device(&ini->ism_dev[0]->dev);
+ lgr->peer_gid = ini->ism_peer_gid[0];
+ lgr->smcd = ini->ism_dev[0];
+ lgr_list = &ini->ism_dev[0]->lgr_list;
lgr_lock = &lgr->smcd->lgr_lock;
lgr->peer_shutdown = 0;
- atomic_inc(&ini->ism_dev->lgr_cnt);
+ atomic_inc(&ini->ism_dev[0]->lgr_cnt);
} else {
/* SMC-R specific settings */
lgr->role = smc->listen_smc ? SMC_SERV : SMC_CLNT;
kfree(lgr);
ism_put_vlan:
if (ini->is_smcd && ini->vlan_id)
- smc_ism_put_vlan(ini->ism_dev, ini->vlan_id);
+ smc_ism_put_vlan(ini->ism_dev[0], ini->vlan_id);
out:
if (rc < 0) {
if (rc == -ENOMEM)
spinlock_t *lgr_lock;
int rc = 0;
- lgr_list = ini->is_smcd ? &ini->ism_dev->lgr_list : &smc_lgr_list.list;
- lgr_lock = ini->is_smcd ? &ini->ism_dev->lgr_lock : &smc_lgr_list.lock;
+ lgr_list = ini->is_smcd ? &ini->ism_dev[0]->lgr_list :
+ &smc_lgr_list.list;
+ lgr_lock = ini->is_smcd ? &ini->ism_dev[0]->lgr_lock :
+ &smc_lgr_list.lock;
ini->first_contact_local = 1;
role = smc->listen_smc ? SMC_SERV : SMC_CLNT;
if (role == SMC_CLNT && ini->first_contact_peer)
list_for_each_entry(lgr, lgr_list, list) {
write_lock_bh(&lgr->conns_lock);
if ((ini->is_smcd ?
- smcd_lgr_match(lgr, ini->ism_dev, ini->ism_peer_gid) :
+ smcd_lgr_match(lgr, ini->ism_dev[0],
+ ini->ism_peer_gid[0]) :
smcr_lgr_match(lgr, ini->ib_lcl, role, ini->ib_clcqpn)) &&
!lgr->sync_err &&
lgr->vlan_id == ini->vlan_id &&