net/smc: separate function for link initialization
Move the initialization of a new link into its own function, separate from smc_lgr_create, to allow more than one link per link group. Do an extra check if the IB device initialization was successful, and reset the link state if any error occurs during smcr_link_init(). And rename two existing functions to use the prefix smcr_ to indicate that they belong to the SMC-R code path. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Reviewed-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
fdff704dc6
Коммит
f3c1deddb2
|
@ -179,7 +179,7 @@ void smc_lgr_cleanup_early(struct smc_connection *conn)
|
|||
* of the DELETE LINK sequence from server; or as server to
|
||||
* initiate the delete processing. See smc_llc_rx_delete_link().
|
||||
*/
|
||||
static int smc_link_send_delete(struct smc_link *lnk, bool orderly)
|
||||
static int smcr_link_send_delete(struct smc_link *lnk, bool orderly)
|
||||
{
|
||||
if (lnk->state == SMC_LNK_ACTIVE &&
|
||||
!smc_llc_send_delete_link(lnk, SMC_LLC_REQ, orderly)) {
|
||||
|
@ -219,7 +219,7 @@ static void smc_lgr_free_work(struct work_struct *work)
|
|||
if (!lgr->is_smcd && !lgr->terminating) {
|
||||
/* try to send del link msg, on error free lgr immediately */
|
||||
if (lnk->state == SMC_LNK_ACTIVE &&
|
||||
!smc_link_send_delete(lnk, true)) {
|
||||
!smcr_link_send_delete(lnk, true)) {
|
||||
/* reschedule in case we never receive a response */
|
||||
smc_lgr_schedule_free_work(lgr);
|
||||
spin_unlock_bh(lgr_lock);
|
||||
|
@ -245,6 +245,64 @@ static void smc_lgr_terminate_work(struct work_struct *work)
|
|||
__smc_lgr_terminate(lgr, true);
|
||||
}
|
||||
|
||||
static int smcr_link_init(struct smc_link *lnk, u8 link_id,
|
||||
struct smc_init_info *ini)
|
||||
{
|
||||
u8 rndvec[3];
|
||||
int rc;
|
||||
|
||||
get_device(&ini->ib_dev->ibdev->dev);
|
||||
atomic_inc(&ini->ib_dev->lnk_cnt);
|
||||
lnk->state = SMC_LNK_ACTIVATING;
|
||||
lnk->link_id = link_id;
|
||||
lnk->smcibdev = ini->ib_dev;
|
||||
lnk->ibport = ini->ib_port;
|
||||
lnk->path_mtu = ini->ib_dev->pattr[ini->ib_port - 1].active_mtu;
|
||||
if (!ini->ib_dev->initialized) {
|
||||
rc = (int)smc_ib_setup_per_ibdev(ini->ib_dev);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
get_random_bytes(rndvec, sizeof(rndvec));
|
||||
lnk->psn_initial = rndvec[0] + (rndvec[1] << 8) +
|
||||
(rndvec[2] << 16);
|
||||
rc = smc_ib_determine_gid(lnk->smcibdev, lnk->ibport,
|
||||
ini->vlan_id, lnk->gid, &lnk->sgid_index);
|
||||
if (rc)
|
||||
goto out;
|
||||
rc = smc_llc_link_init(lnk);
|
||||
if (rc)
|
||||
goto out;
|
||||
rc = smc_wr_alloc_link_mem(lnk);
|
||||
if (rc)
|
||||
goto clear_llc_lnk;
|
||||
rc = smc_ib_create_protection_domain(lnk);
|
||||
if (rc)
|
||||
goto free_link_mem;
|
||||
rc = smc_ib_create_queue_pair(lnk);
|
||||
if (rc)
|
||||
goto dealloc_pd;
|
||||
rc = smc_wr_create_link(lnk);
|
||||
if (rc)
|
||||
goto destroy_qp;
|
||||
return 0;
|
||||
|
||||
destroy_qp:
|
||||
smc_ib_destroy_queue_pair(lnk);
|
||||
dealloc_pd:
|
||||
smc_ib_dealloc_protection_domain(lnk);
|
||||
free_link_mem:
|
||||
smc_wr_free_link_mem(lnk);
|
||||
clear_llc_lnk:
|
||||
smc_llc_link_clear(lnk);
|
||||
out:
|
||||
put_device(&ini->ib_dev->ibdev->dev);
|
||||
memset(lnk, 0, sizeof(struct smc_link));
|
||||
if (!atomic_dec_return(&ini->ib_dev->lnk_cnt))
|
||||
wake_up(&ini->ib_dev->lnks_deleted);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* create a new SMC link group */
|
||||
static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
||||
{
|
||||
|
@ -252,7 +310,6 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
|||
struct list_head *lgr_list;
|
||||
struct smc_link *lnk;
|
||||
spinlock_t *lgr_lock;
|
||||
u8 rndvec[3];
|
||||
int rc = 0;
|
||||
int i;
|
||||
|
||||
|
@ -297,48 +354,17 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
|||
atomic_inc(&ini->ism_dev->lgr_cnt);
|
||||
} else {
|
||||
/* SMC-R specific settings */
|
||||
get_device(&ini->ib_dev->ibdev->dev);
|
||||
lgr->role = smc->listen_smc ? SMC_SERV : SMC_CLNT;
|
||||
memcpy(lgr->peer_systemid, ini->ib_lcl->id_for_peer,
|
||||
SMC_SYSTEMID_LEN);
|
||||
|
||||
lnk = &lgr->lnk[SMC_SINGLE_LINK];
|
||||
/* initialize link */
|
||||
lnk->state = SMC_LNK_ACTIVATING;
|
||||
lnk->link_id = SMC_SINGLE_LINK;
|
||||
lnk->smcibdev = ini->ib_dev;
|
||||
lnk->ibport = ini->ib_port;
|
||||
rc = smcr_link_init(lnk, SMC_SINGLE_LINK, ini);
|
||||
if (rc)
|
||||
goto free_lgr;
|
||||
lgr_list = &smc_lgr_list.list;
|
||||
lgr_lock = &smc_lgr_list.lock;
|
||||
lnk->path_mtu =
|
||||
ini->ib_dev->pattr[ini->ib_port - 1].active_mtu;
|
||||
if (!ini->ib_dev->initialized)
|
||||
smc_ib_setup_per_ibdev(ini->ib_dev);
|
||||
get_random_bytes(rndvec, sizeof(rndvec));
|
||||
lnk->psn_initial = rndvec[0] + (rndvec[1] << 8) +
|
||||
(rndvec[2] << 16);
|
||||
rc = smc_ib_determine_gid(lnk->smcibdev, lnk->ibport,
|
||||
ini->vlan_id, lnk->gid,
|
||||
&lnk->sgid_index);
|
||||
if (rc)
|
||||
goto free_lgr;
|
||||
rc = smc_llc_link_init(lnk);
|
||||
if (rc)
|
||||
goto free_lgr;
|
||||
rc = smc_wr_alloc_link_mem(lnk);
|
||||
if (rc)
|
||||
goto clear_llc_lnk;
|
||||
rc = smc_ib_create_protection_domain(lnk);
|
||||
if (rc)
|
||||
goto free_link_mem;
|
||||
rc = smc_ib_create_queue_pair(lnk);
|
||||
if (rc)
|
||||
goto dealloc_pd;
|
||||
rc = smc_wr_create_link(lnk);
|
||||
if (rc)
|
||||
goto destroy_qp;
|
||||
atomic_inc(&lgr_cnt);
|
||||
atomic_inc(&ini->ib_dev->lnk_cnt);
|
||||
}
|
||||
smc->conn.lgr = lgr;
|
||||
spin_lock_bh(lgr_lock);
|
||||
|
@ -346,14 +372,6 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
|||
spin_unlock_bh(lgr_lock);
|
||||
return 0;
|
||||
|
||||
destroy_qp:
|
||||
smc_ib_destroy_queue_pair(lnk);
|
||||
dealloc_pd:
|
||||
smc_ib_dealloc_protection_domain(lnk);
|
||||
free_link_mem:
|
||||
smc_wr_free_link_mem(lnk);
|
||||
clear_llc_lnk:
|
||||
smc_llc_link_clear(lnk);
|
||||
free_lgr:
|
||||
kfree(lgr);
|
||||
ism_put_vlan:
|
||||
|
@ -417,7 +435,7 @@ void smc_conn_free(struct smc_connection *conn)
|
|||
smc_lgr_schedule_free_work(lgr);
|
||||
}
|
||||
|
||||
static void smc_link_clear(struct smc_link *lnk)
|
||||
static void smcr_link_clear(struct smc_link *lnk)
|
||||
{
|
||||
lnk->peer_qpn = 0;
|
||||
smc_llc_link_clear(lnk);
|
||||
|
@ -426,6 +444,7 @@ static void smc_link_clear(struct smc_link *lnk)
|
|||
smc_ib_destroy_queue_pair(lnk);
|
||||
smc_ib_dealloc_protection_domain(lnk);
|
||||
smc_wr_free_link_mem(lnk);
|
||||
put_device(&lnk->smcibdev->ibdev->dev);
|
||||
if (!atomic_dec_return(&lnk->smcibdev->lnk_cnt))
|
||||
wake_up(&lnk->smcibdev->lnks_deleted);
|
||||
}
|
||||
|
@ -512,8 +531,7 @@ static void smc_lgr_free(struct smc_link_group *lgr)
|
|||
if (!atomic_dec_return(&lgr->smcd->lgr_cnt))
|
||||
wake_up(&lgr->smcd->lgrs_deleted);
|
||||
} else {
|
||||
smc_link_clear(&lgr->lnk[SMC_SINGLE_LINK]);
|
||||
put_device(&lgr->lnk[SMC_SINGLE_LINK].smcibdev->ibdev->dev);
|
||||
smcr_link_clear(&lgr->lnk[SMC_SINGLE_LINK]);
|
||||
if (!atomic_dec_return(&lgr_cnt))
|
||||
wake_up(&lgrs_deleted);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче