net/smc: multiple link support and LLC flow for smc_llc_do_confirm_rkey
Adapt smc_llc_do_confirm_rkey() to use the LLC flow and support the rkeys of multiple links when the CONFIRM_RKEY LLC message is build. 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:
parent
0fb0b02bd6
commit
3d88a21b0c
|
@ -123,8 +123,6 @@ struct smc_link {
|
||||||
struct delayed_work llc_testlink_wrk; /* testlink worker */
|
struct delayed_work llc_testlink_wrk; /* testlink worker */
|
||||||
struct completion llc_testlink_resp; /* wait for rx of testlink */
|
struct completion llc_testlink_resp; /* wait for rx of testlink */
|
||||||
int llc_testlink_time; /* testlink interval */
|
int llc_testlink_time; /* testlink interval */
|
||||||
struct completion llc_confirm_rkey_resp; /* w4 rx of cnf rkey */
|
|
||||||
int llc_confirm_rkey_resp_rc; /* rc from cnf rkey */
|
|
||||||
struct completion llc_delete_rkey_resp; /* w4 rx of del rkey */
|
struct completion llc_delete_rkey_resp; /* w4 rx of del rkey */
|
||||||
int llc_delete_rkey_resp_rc; /* rc from del rkey */
|
int llc_delete_rkey_resp_rc; /* rc from del rkey */
|
||||||
struct mutex llc_delete_rkey_mutex; /* serialize usage */
|
struct mutex llc_delete_rkey_mutex; /* serialize usage */
|
||||||
|
|
|
@ -369,27 +369,44 @@ int smc_llc_send_confirm_link(struct smc_link *link,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send LLC confirm rkey request */
|
/* send LLC confirm rkey request */
|
||||||
static int smc_llc_send_confirm_rkey(struct smc_link *link,
|
static int smc_llc_send_confirm_rkey(struct smc_link *send_link,
|
||||||
struct smc_buf_desc *rmb_desc)
|
struct smc_buf_desc *rmb_desc)
|
||||||
{
|
{
|
||||||
struct smc_llc_msg_confirm_rkey *rkeyllc;
|
struct smc_llc_msg_confirm_rkey *rkeyllc;
|
||||||
struct smc_wr_tx_pend_priv *pend;
|
struct smc_wr_tx_pend_priv *pend;
|
||||||
struct smc_wr_buf *wr_buf;
|
struct smc_wr_buf *wr_buf;
|
||||||
int rc;
|
struct smc_link *link;
|
||||||
|
int i, rc, rtok_ix;
|
||||||
|
|
||||||
rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
|
rc = smc_llc_add_pending_send(send_link, &wr_buf, &pend);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
rkeyllc = (struct smc_llc_msg_confirm_rkey *)wr_buf;
|
rkeyllc = (struct smc_llc_msg_confirm_rkey *)wr_buf;
|
||||||
memset(rkeyllc, 0, sizeof(*rkeyllc));
|
memset(rkeyllc, 0, sizeof(*rkeyllc));
|
||||||
rkeyllc->hd.common.type = SMC_LLC_CONFIRM_RKEY;
|
rkeyllc->hd.common.type = SMC_LLC_CONFIRM_RKEY;
|
||||||
rkeyllc->hd.length = sizeof(struct smc_llc_msg_confirm_rkey);
|
rkeyllc->hd.length = sizeof(struct smc_llc_msg_confirm_rkey);
|
||||||
|
|
||||||
|
rtok_ix = 1;
|
||||||
|
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
|
||||||
|
link = &send_link->lgr->lnk[i];
|
||||||
|
if (link->state == SMC_LNK_ACTIVE && link != send_link) {
|
||||||
|
rkeyllc->rtoken[rtok_ix].link_id = link->link_id;
|
||||||
|
rkeyllc->rtoken[rtok_ix].rmb_key =
|
||||||
|
htonl(rmb_desc->mr_rx[link->link_idx]->rkey);
|
||||||
|
rkeyllc->rtoken[rtok_ix].rmb_vaddr = cpu_to_be64(
|
||||||
|
(u64)sg_dma_address(
|
||||||
|
rmb_desc->sgt[link->link_idx].sgl));
|
||||||
|
rtok_ix++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* rkey of send_link is in rtoken[0] */
|
||||||
|
rkeyllc->rtoken[0].num_rkeys = rtok_ix - 1;
|
||||||
rkeyllc->rtoken[0].rmb_key =
|
rkeyllc->rtoken[0].rmb_key =
|
||||||
htonl(rmb_desc->mr_rx[link->link_idx]->rkey);
|
htonl(rmb_desc->mr_rx[send_link->link_idx]->rkey);
|
||||||
rkeyllc->rtoken[0].rmb_vaddr = cpu_to_be64(
|
rkeyllc->rtoken[0].rmb_vaddr = cpu_to_be64(
|
||||||
(u64)sg_dma_address(rmb_desc->sgt[link->link_idx].sgl));
|
(u64)sg_dma_address(rmb_desc->sgt[send_link->link_idx].sgl));
|
||||||
/* send llc message */
|
/* send llc message */
|
||||||
rc = smc_wr_tx_send(link, pend);
|
rc = smc_wr_tx_send(send_link, pend);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,6 +729,7 @@ static void smc_llc_rx_response(struct smc_link *link,
|
||||||
break;
|
break;
|
||||||
case SMC_LLC_ADD_LINK:
|
case SMC_LLC_ADD_LINK:
|
||||||
case SMC_LLC_CONFIRM_LINK:
|
case SMC_LLC_CONFIRM_LINK:
|
||||||
|
case SMC_LLC_CONFIRM_RKEY:
|
||||||
/* assign responses to the local flow, we requested them */
|
/* assign responses to the local flow, we requested them */
|
||||||
smc_llc_flow_qentry_set(&link->lgr->llc_flow_lcl, qentry);
|
smc_llc_flow_qentry_set(&link->lgr->llc_flow_lcl, qentry);
|
||||||
wake_up_interruptible(&link->lgr->llc_waiter);
|
wake_up_interruptible(&link->lgr->llc_waiter);
|
||||||
|
@ -720,11 +738,6 @@ static void smc_llc_rx_response(struct smc_link *link,
|
||||||
if (link->lgr->role == SMC_SERV)
|
if (link->lgr->role == SMC_SERV)
|
||||||
smc_lgr_schedule_free_work_fast(link->lgr);
|
smc_lgr_schedule_free_work_fast(link->lgr);
|
||||||
break;
|
break;
|
||||||
case SMC_LLC_CONFIRM_RKEY:
|
|
||||||
link->llc_confirm_rkey_resp_rc = llc->raw.hdr.flags &
|
|
||||||
SMC_LLC_FLAG_RKEY_NEG;
|
|
||||||
complete(&link->llc_confirm_rkey_resp);
|
|
||||||
break;
|
|
||||||
case SMC_LLC_CONFIRM_RKEY_CONT:
|
case SMC_LLC_CONFIRM_RKEY_CONT:
|
||||||
/* unused as long as we don't send this type of msg */
|
/* unused as long as we don't send this type of msg */
|
||||||
break;
|
break;
|
||||||
|
@ -837,7 +850,6 @@ void smc_llc_lgr_clear(struct smc_link_group *lgr)
|
||||||
|
|
||||||
int smc_llc_link_init(struct smc_link *link)
|
int smc_llc_link_init(struct smc_link *link)
|
||||||
{
|
{
|
||||||
init_completion(&link->llc_confirm_rkey_resp);
|
|
||||||
init_completion(&link->llc_delete_rkey_resp);
|
init_completion(&link->llc_delete_rkey_resp);
|
||||||
mutex_init(&link->llc_delete_rkey_mutex);
|
mutex_init(&link->llc_delete_rkey_mutex);
|
||||||
init_completion(&link->llc_testlink_resp);
|
init_completion(&link->llc_testlink_resp);
|
||||||
|
@ -870,23 +882,30 @@ void smc_llc_link_clear(struct smc_link *link)
|
||||||
smc_wr_wakeup_tx_wait(link);
|
smc_wr_wakeup_tx_wait(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register a new rtoken at the remote peer */
|
/* register a new rtoken at the remote peer (for all links) */
|
||||||
int smc_llc_do_confirm_rkey(struct smc_link *link,
|
int smc_llc_do_confirm_rkey(struct smc_link *send_link,
|
||||||
struct smc_buf_desc *rmb_desc)
|
struct smc_buf_desc *rmb_desc)
|
||||||
{
|
{
|
||||||
int rc;
|
struct smc_link_group *lgr = send_link->lgr;
|
||||||
|
struct smc_llc_qentry *qentry = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
/* protected by mutex smc_create_lgr_pending */
|
rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
|
||||||
reinit_completion(&link->llc_confirm_rkey_resp);
|
|
||||||
rc = smc_llc_send_confirm_rkey(link, rmb_desc);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
rc = smc_llc_send_confirm_rkey(send_link, rmb_desc);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
/* receive CONFIRM RKEY response from server over RoCE fabric */
|
/* receive CONFIRM RKEY response from server over RoCE fabric */
|
||||||
rc = wait_for_completion_interruptible_timeout(
|
qentry = smc_llc_wait(lgr, send_link, SMC_LLC_WAIT_TIME,
|
||||||
&link->llc_confirm_rkey_resp, SMC_LLC_WAIT_TIME);
|
SMC_LLC_CONFIRM_RKEY);
|
||||||
if (rc <= 0 || link->llc_confirm_rkey_resp_rc)
|
if (!qentry || (qentry->msg.raw.hdr.flags & SMC_LLC_FLAG_RKEY_NEG))
|
||||||
return -EFAULT;
|
rc = -EFAULT;
|
||||||
return 0;
|
out:
|
||||||
|
if (qentry)
|
||||||
|
smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
|
||||||
|
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unregister an rtoken at the remote peer */
|
/* unregister an rtoken at the remote peer */
|
||||||
|
|
|
@ -59,7 +59,7 @@ int smc_llc_link_init(struct smc_link *link);
|
||||||
void smc_llc_link_active(struct smc_link *link);
|
void smc_llc_link_active(struct smc_link *link);
|
||||||
void smc_llc_link_deleting(struct smc_link *link);
|
void smc_llc_link_deleting(struct smc_link *link);
|
||||||
void smc_llc_link_clear(struct smc_link *link);
|
void smc_llc_link_clear(struct smc_link *link);
|
||||||
int smc_llc_do_confirm_rkey(struct smc_link *link,
|
int smc_llc_do_confirm_rkey(struct smc_link *send_link,
|
||||||
struct smc_buf_desc *rmb_desc);
|
struct smc_buf_desc *rmb_desc);
|
||||||
int smc_llc_do_delete_rkey(struct smc_link *link,
|
int smc_llc_do_delete_rkey(struct smc_link *link,
|
||||||
struct smc_buf_desc *rmb_desc);
|
struct smc_buf_desc *rmb_desc);
|
||||||
|
|
Loading…
Reference in New Issue