diff options
author | Karsten Graul <kgraul@linux.ibm.com> | 2020-05-03 14:38:42 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-05-03 16:06:25 -0700 |
commit | b1570a87f57e94e9f74b8942840f9bd16bd1aba5 (patch) | |
tree | 4277406c673613a7fefa27fc3ff839587c867188 | |
parent | 87f88cda2128a72d79d4cc700729488af1081a06 (diff) |
net/smc: final part of add link processing as SMC client
This patch finalizes the ADD_LINK processing of new links. Receive the
CONFIRM_LINK request from peer, complete the link initialization,
register all used buffers with the IB device and finally send the
CONFIRM_LINK response, which completes the ADD_LINK processing.
And activate smc_llc_cli_add_link() in af_smc.c.
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>
-rw-r--r-- | net/smc/af_smc.c | 2 | ||||
-rw-r--r-- | net/smc/smc_llc.c | 73 | ||||
-rw-r--r-- | net/smc/smc_llc.h | 1 |
3 files changed, 72 insertions, 4 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 6663a63be9e4..1afb6e4275f2 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -427,7 +427,7 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc) return rc; } smc_llc_flow_qentry_clr(&link->lgr->llc_flow_lcl); - /* tbd: call smc_llc_cli_add_link(link, qentry); */ + smc_llc_cli_add_link(link, qentry); return 0; } diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c index a06b618f172e..d56ca60597d4 100644 --- a/net/smc/smc_llc.c +++ b/net/smc/smc_llc.c @@ -381,7 +381,7 @@ int smc_llc_send_confirm_link(struct smc_link *link, hton24(confllc->sender_qp_num, link->roce_qp->qp_num); confllc->link_num = link->link_id; memcpy(confllc->link_uid, lgr->id, SMC_LGR_ID_SIZE); - confllc->max_links = SMC_LLC_ADD_LNK_MAX_LINKS; /* enforce peer resp. */ + confllc->max_links = SMC_LLC_ADD_LNK_MAX_LINKS; /* send llc message */ rc = smc_wr_tx_send(link, pend); return rc; @@ -724,6 +724,61 @@ static int smc_llc_cli_add_link_reject(struct smc_llc_qentry *qentry) return smc_llc_send_message(qentry->link, &qentry->msg); } +static int smc_llc_cli_conf_link(struct smc_link *link, + struct smc_init_info *ini, + struct smc_link *link_new, + enum smc_lgr_type lgr_new_t) +{ + struct smc_link_group *lgr = link->lgr; + struct smc_llc_msg_del_link *del_llc; + struct smc_llc_qentry *qentry = NULL; + int rc = 0; + + /* receive CONFIRM LINK request over RoCE fabric */ + qentry = smc_llc_wait(lgr, NULL, SMC_LLC_WAIT_FIRST_TIME, 0); + if (!qentry) { + rc = smc_llc_send_delete_link(link, link_new->link_id, + SMC_LLC_REQ, false, + SMC_LLC_DEL_LOST_PATH); + return -ENOLINK; + } + if (qentry->msg.raw.hdr.common.type != SMC_LLC_CONFIRM_LINK) { + /* received DELETE_LINK instead */ + del_llc = &qentry->msg.delete_link; + qentry->msg.raw.hdr.flags |= SMC_LLC_FLAG_RESP; + smc_llc_send_message(link, &qentry->msg); + smc_llc_flow_qentry_del(&lgr->llc_flow_lcl); + return -ENOLINK; + } + smc_llc_flow_qentry_del(&lgr->llc_flow_lcl); + + rc = smc_ib_modify_qp_rts(link_new); + if (rc) { + smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, + false, SMC_LLC_DEL_LOST_PATH); + return -ENOLINK; + } + smc_wr_remember_qp_attr(link_new); + + rc = smcr_buf_reg_lgr(link_new); + if (rc) { + smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, + false, SMC_LLC_DEL_LOST_PATH); + return -ENOLINK; + } + + /* send CONFIRM LINK response over RoCE fabric */ + rc = smc_llc_send_confirm_link(link_new, SMC_LLC_RESP); + if (rc) { + smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, + false, SMC_LLC_DEL_LOST_PATH); + return -ENOLINK; + } + smc_llc_link_active(link_new); + lgr->type = lgr_new_t; + return 0; +} + static void smc_llc_save_add_link_info(struct smc_link *link, struct smc_llc_msg_add_link *add_llc) { @@ -785,7 +840,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry) rc = 0; goto out_clear_lnk; } - /* tbd: rc = smc_llc_cli_conf_link(link, &ini, lnk_new, lgr_new_t); */ + rc = smc_llc_cli_conf_link(link, &ini, lnk_new, lgr_new_t); if (!rc) goto out; out_clear_lnk: @@ -797,6 +852,17 @@ out: return rc; } +static void smc_llc_process_cli_add_link(struct smc_link_group *lgr) +{ + struct smc_llc_qentry *qentry; + + qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl); + + mutex_lock(&lgr->llc_conf_mutex); + smc_llc_cli_add_link(qentry->link, qentry); + mutex_unlock(&lgr->llc_conf_mutex); +} + /* worker to process an add link message */ static void smc_llc_add_link_work(struct work_struct *work) { @@ -809,7 +875,8 @@ static void smc_llc_add_link_work(struct work_struct *work) goto out; } - /* tbd: call smc_llc_process_cli_add_link(lgr); */ + if (lgr->role == SMC_CLNT) + smc_llc_process_cli_add_link(lgr); /* tbd: call smc_llc_process_srv_add_link(lgr); */ out: smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl); diff --git a/net/smc/smc_llc.h b/net/smc/smc_llc.h index 97a4f02f5a93..7c314bbef8c8 100644 --- a/net/smc/smc_llc.h +++ b/net/smc/smc_llc.h @@ -88,6 +88,7 @@ struct smc_llc_qentry *smc_llc_wait(struct smc_link_group *lgr, int time_out, u8 exp_msg); struct smc_llc_qentry *smc_llc_flow_qentry_clr(struct smc_llc_flow *flow); void smc_llc_flow_qentry_del(struct smc_llc_flow *flow); +int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry); int smc_llc_init(void) __init; #endif /* SMC_LLC_H */ |