Skip to content

Commit 336ba09

Browse files
karstengrdavem330
authored andcommitted
net/smc: first part of add link processing as SMC client
First set of functions to process an ADD_LINK LLC request as an SMC client. Find an alternate IB device, determine the new link group type and get the index for the new link. Then ready the link, map the buffers and send an ADD_LINK LLC response. If any error occurs, send a reject LLC message and terminate the processing. Add smc_llc_alloc_alt_link() to find a free link index for a new link, depending on the new link group type. Signed-off-by: Karsten Graul <[email protected]> Reviewed-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d1a2250 commit 336ba09

File tree

3 files changed

+111
-2
lines changed

3 files changed

+111
-2
lines changed

net/smc/smc_core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ static u8 smcr_next_link_id(struct smc_link_group *lgr)
273273
return link_id;
274274
}
275275

276-
static int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
277-
u8 link_idx, struct smc_init_info *ini)
276+
int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
277+
u8 link_idx, struct smc_init_info *ini)
278278
{
279279
u8 rndvec[3];
280280
int rc;

net/smc/smc_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ void smc_lgr_schedule_free_work_fast(struct smc_link_group *lgr);
374374
int smc_core_init(void);
375375
void smc_core_exit(void);
376376

377+
int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
378+
u8 link_idx, struct smc_init_info *ini);
377379
void smcr_link_clear(struct smc_link *lnk);
378380
int smcr_buf_map_lgr(struct smc_link *lnk);
379381
int smcr_buf_reg_lgr(struct smc_link *lnk);

net/smc/smc_llc.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "smc_core.h"
1818
#include "smc_clc.h"
1919
#include "smc_llc.h"
20+
#include "smc_pnet.h"
2021

2122
#define SMC_LLC_DATA_LEN 40
2223

@@ -541,6 +542,112 @@ static int smc_llc_send_message(struct smc_link *link, void *llcbuf)
541542

542543
/********************************* receive ***********************************/
543544

545+
static int smc_llc_alloc_alt_link(struct smc_link_group *lgr,
546+
enum smc_lgr_type lgr_new_t)
547+
{
548+
int i;
549+
550+
if (lgr->type == SMC_LGR_SYMMETRIC ||
551+
(lgr->type != SMC_LGR_SINGLE &&
552+
(lgr_new_t == SMC_LGR_ASYMMETRIC_LOCAL ||
553+
lgr_new_t == SMC_LGR_ASYMMETRIC_PEER)))
554+
return -EMLINK;
555+
556+
if (lgr_new_t == SMC_LGR_ASYMMETRIC_LOCAL ||
557+
lgr_new_t == SMC_LGR_ASYMMETRIC_PEER) {
558+
for (i = SMC_LINKS_PER_LGR_MAX - 1; i >= 0; i--)
559+
if (lgr->lnk[i].state == SMC_LNK_UNUSED)
560+
return i;
561+
} else {
562+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++)
563+
if (lgr->lnk[i].state == SMC_LNK_UNUSED)
564+
return i;
565+
}
566+
return -EMLINK;
567+
}
568+
569+
/* prepare and send an add link reject response */
570+
static int smc_llc_cli_add_link_reject(struct smc_llc_qentry *qentry)
571+
{
572+
qentry->msg.raw.hdr.flags |= SMC_LLC_FLAG_RESP;
573+
qentry->msg.raw.hdr.flags |= SMC_LLC_FLAG_ADD_LNK_REJ;
574+
qentry->msg.raw.hdr.add_link_rej_rsn = SMC_LLC_REJ_RSN_NO_ALT_PATH;
575+
return smc_llc_send_message(qentry->link, &qentry->msg);
576+
}
577+
578+
static void smc_llc_save_add_link_info(struct smc_link *link,
579+
struct smc_llc_msg_add_link *add_llc)
580+
{
581+
link->peer_qpn = ntoh24(add_llc->sender_qp_num);
582+
memcpy(link->peer_gid, add_llc->sender_gid, SMC_GID_SIZE);
583+
memcpy(link->peer_mac, add_llc->sender_mac, ETH_ALEN);
584+
link->peer_psn = ntoh24(add_llc->initial_psn);
585+
link->peer_mtu = add_llc->qp_mtu;
586+
}
587+
588+
/* as an SMC client, process an add link request */
589+
int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)
590+
{
591+
struct smc_llc_msg_add_link *llc = &qentry->msg.add_link;
592+
enum smc_lgr_type lgr_new_t = SMC_LGR_SYMMETRIC;
593+
struct smc_link_group *lgr = smc_get_lgr(link);
594+
struct smc_link *lnk_new = NULL;
595+
struct smc_init_info ini;
596+
int lnk_idx, rc = 0;
597+
598+
ini.vlan_id = lgr->vlan_id;
599+
smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);
600+
if (!memcmp(llc->sender_gid, link->peer_gid, SMC_GID_SIZE) &&
601+
!memcmp(llc->sender_mac, link->peer_mac, ETH_ALEN)) {
602+
if (!ini.ib_dev)
603+
goto out_reject;
604+
lgr_new_t = SMC_LGR_ASYMMETRIC_PEER;
605+
}
606+
if (!ini.ib_dev) {
607+
lgr_new_t = SMC_LGR_ASYMMETRIC_LOCAL;
608+
ini.ib_dev = link->smcibdev;
609+
ini.ib_port = link->ibport;
610+
}
611+
lnk_idx = smc_llc_alloc_alt_link(lgr, lgr_new_t);
612+
if (lnk_idx < 0)
613+
goto out_reject;
614+
lnk_new = &lgr->lnk[lnk_idx];
615+
rc = smcr_link_init(lgr, lnk_new, lnk_idx, &ini);
616+
if (rc)
617+
goto out_reject;
618+
smc_llc_save_add_link_info(lnk_new, llc);
619+
lnk_new->link_id = llc->link_num;
620+
621+
rc = smc_ib_ready_link(lnk_new);
622+
if (rc)
623+
goto out_clear_lnk;
624+
625+
rc = smcr_buf_map_lgr(lnk_new);
626+
if (rc)
627+
goto out_clear_lnk;
628+
629+
rc = smc_llc_send_add_link(link,
630+
lnk_new->smcibdev->mac[ini.ib_port - 1],
631+
lnk_new->gid, lnk_new, SMC_LLC_RESP);
632+
if (rc)
633+
goto out_clear_lnk;
634+
/* tbd: rc = smc_llc_cli_rkey_exchange(link, lnk_new); */
635+
if (rc) {
636+
rc = 0;
637+
goto out_clear_lnk;
638+
}
639+
/* tbd: rc = smc_llc_cli_conf_link(link, &ini, lnk_new, lgr_new_t); */
640+
if (!rc)
641+
goto out;
642+
out_clear_lnk:
643+
smcr_link_clear(lnk_new);
644+
out_reject:
645+
smc_llc_cli_add_link_reject(qentry);
646+
out:
647+
kfree(qentry);
648+
return rc;
649+
}
650+
544651
/* worker to process an add link message */
545652
static void smc_llc_add_link_work(struct work_struct *work)
546653
{

0 commit comments

Comments
 (0)