net/smc: register new rmbs with the peer
Register new rmb buffers with the remote peer by exchanging a confirm_rkey llc message. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
569bc64365
commit
44aa81ce95
|
@ -293,14 +293,22 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc)
|
|||
smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC);
|
||||
}
|
||||
|
||||
/* register a new rmb */
|
||||
static int smc_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc)
|
||||
/* register a new rmb, optionally send confirm_rkey msg to register with peer */
|
||||
static int smc_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc,
|
||||
bool conf_rkey)
|
||||
{
|
||||
/* register memory region for new rmb */
|
||||
if (smc_wr_reg_send(link, rmb_desc->mr_rx[SMC_SINGLE_LINK])) {
|
||||
rmb_desc->regerr = 1;
|
||||
return -EFAULT;
|
||||
}
|
||||
if (!conf_rkey)
|
||||
return 0;
|
||||
/* exchange confirm_rkey msg with peer */
|
||||
if (smc_llc_do_confirm_rkey(link, rmb_desc)) {
|
||||
rmb_desc->regerr = 1;
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -334,7 +342,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
|
|||
|
||||
smc_wr_remember_qp_attr(link);
|
||||
|
||||
if (smc_reg_rmb(link, smc->conn.rmb_desc))
|
||||
if (smc_reg_rmb(link, smc->conn.rmb_desc, false))
|
||||
return SMC_CLC_DECL_INTERR;
|
||||
|
||||
/* send CONFIRM LINK response over RoCE fabric */
|
||||
|
@ -488,7 +496,7 @@ static int smc_connect_rdma(struct smc_sock *smc)
|
|||
}
|
||||
} else {
|
||||
if (!smc->conn.rmb_desc->reused) {
|
||||
if (smc_reg_rmb(link, smc->conn.rmb_desc)) {
|
||||
if (smc_reg_rmb(link, smc->conn.rmb_desc, true)) {
|
||||
reason_code = SMC_CLC_DECL_INTERR;
|
||||
goto decline_rdma_unlock;
|
||||
}
|
||||
|
@ -729,7 +737,7 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
|
|||
|
||||
link = &lgr->lnk[SMC_SINGLE_LINK];
|
||||
|
||||
if (smc_reg_rmb(link, smc->conn.rmb_desc))
|
||||
if (smc_reg_rmb(link, smc->conn.rmb_desc, false))
|
||||
return SMC_CLC_DECL_INTERR;
|
||||
|
||||
/* send CONFIRM LINK request to client over the RoCE fabric */
|
||||
|
@ -866,7 +874,7 @@ static void smc_listen_work(struct work_struct *work)
|
|||
|
||||
if (local_contact != SMC_FIRST_CONTACT) {
|
||||
if (!new_smc->conn.rmb_desc->reused) {
|
||||
if (smc_reg_rmb(link, new_smc->conn.rmb_desc)) {
|
||||
if (smc_reg_rmb(link, new_smc->conn.rmb_desc, true)) {
|
||||
reason_code = SMC_CLC_DECL_INTERR;
|
||||
goto decline_rdma_unlock;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,7 @@ static int smc_lgr_create(struct smc_sock *smc,
|
|||
init_completion(&lnk->llc_confirm_resp);
|
||||
init_completion(&lnk->llc_add);
|
||||
init_completion(&lnk->llc_add_resp);
|
||||
init_completion(&lnk->llc_confirm_rkey);
|
||||
|
||||
smc->conn.lgr = lgr;
|
||||
rwlock_init(&lgr->conns_lock);
|
||||
|
|
|
@ -105,6 +105,8 @@ struct smc_link {
|
|||
struct delayed_work llc_testlink_wrk; /* testlink worker */
|
||||
struct completion llc_testlink_resp; /* wait for rx of testlink */
|
||||
int llc_testlink_time; /* testlink interval */
|
||||
struct completion llc_confirm_rkey; /* wait 4 rx of cnf rkey */
|
||||
int llc_confirm_rkey_rc; /* rc from cnf rkey msg */
|
||||
};
|
||||
|
||||
/* For now we just allow one parallel link per link group. The SMC protocol
|
||||
|
|
|
@ -214,6 +214,31 @@ int smc_llc_send_confirm_link(struct smc_link *link, u8 mac[],
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* send LLC confirm rkey request */
|
||||
static int smc_llc_send_confirm_rkey(struct smc_link *link,
|
||||
struct smc_buf_desc *rmb_desc)
|
||||
{
|
||||
struct smc_llc_msg_confirm_rkey *rkeyllc;
|
||||
struct smc_wr_tx_pend_priv *pend;
|
||||
struct smc_wr_buf *wr_buf;
|
||||
int rc;
|
||||
|
||||
rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
|
||||
if (rc)
|
||||
return rc;
|
||||
rkeyllc = (struct smc_llc_msg_confirm_rkey *)wr_buf;
|
||||
memset(rkeyllc, 0, sizeof(*rkeyllc));
|
||||
rkeyllc->hd.common.type = SMC_LLC_CONFIRM_RKEY;
|
||||
rkeyllc->hd.length = sizeof(struct smc_llc_msg_confirm_rkey);
|
||||
rkeyllc->rtoken[0].rmb_key =
|
||||
htonl(rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
|
||||
rkeyllc->rtoken[0].rmb_vaddr = cpu_to_be64(
|
||||
(u64)sg_dma_address(rmb_desc->sgt[SMC_SINGLE_LINK].sgl));
|
||||
/* send llc message */
|
||||
rc = smc_wr_tx_send(link, pend);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send ADD LINK request or response */
|
||||
int smc_llc_send_add_link(struct smc_link *link, u8 mac[],
|
||||
union ib_gid *gid,
|
||||
|
@ -413,7 +438,9 @@ static void smc_llc_rx_confirm_rkey(struct smc_link *link,
|
|||
lgr = container_of(link, struct smc_link_group, lnk[SMC_SINGLE_LINK]);
|
||||
|
||||
if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
|
||||
/* unused as long as we don't send this type of msg */
|
||||
link->llc_confirm_rkey_rc = llc->hd.flags &
|
||||
SMC_LLC_FLAG_RKEY_NEG;
|
||||
complete(&link->llc_confirm_rkey);
|
||||
} else {
|
||||
rc = smc_rtoken_add(lgr,
|
||||
llc->rtoken[0].rmb_vaddr,
|
||||
|
@ -503,7 +530,7 @@ static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)
|
|||
}
|
||||
}
|
||||
|
||||
/***************************** worker ****************************************/
|
||||
/***************************** worker, utils *********************************/
|
||||
|
||||
static void smc_llc_testlink_work(struct work_struct *work)
|
||||
{
|
||||
|
@ -562,6 +589,22 @@ void smc_llc_link_flush(struct smc_link *link)
|
|||
cancel_delayed_work_sync(&link->llc_testlink_wrk);
|
||||
}
|
||||
|
||||
/* register a new rtoken at the remote peer */
|
||||
int smc_llc_do_confirm_rkey(struct smc_link *link,
|
||||
struct smc_buf_desc *rmb_desc)
|
||||
{
|
||||
int rc;
|
||||
|
||||
reinit_completion(&link->llc_confirm_rkey);
|
||||
smc_llc_send_confirm_rkey(link, rmb_desc);
|
||||
/* receive CONFIRM RKEY response from server over RoCE fabric */
|
||||
rc = wait_for_completion_interruptible_timeout(&link->llc_confirm_rkey,
|
||||
SMC_LLC_WAIT_TIME);
|
||||
if (rc <= 0 || link->llc_confirm_rkey_rc)
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************** init, exit, misc ******************************/
|
||||
|
||||
static struct smc_wr_rx_handler smc_llc_rx_handlers[] = {
|
||||
|
|
|
@ -47,6 +47,8 @@ int smc_llc_send_test_link(struct smc_link *lnk, u8 user_data[16],
|
|||
void smc_llc_link_active(struct smc_link *link, int testlink_time);
|
||||
void smc_llc_link_inactive(struct smc_link *link);
|
||||
void smc_llc_link_flush(struct smc_link *link);
|
||||
int smc_llc_do_confirm_rkey(struct smc_link *link,
|
||||
struct smc_buf_desc *rmb_desc);
|
||||
int smc_llc_init(void) __init;
|
||||
|
||||
#endif /* SMC_LLC_H */
|
||||
|
|
Loading…
Reference in New Issue