Commit b9247544 authored by Karsten Graul's avatar Karsten Graul Committed by David S. Miller

net/smc: convert static link ID instances to support multiple links

As a preparation for the support of multiple links remove the usage of
a static link id (SMC_SINGLE_LINK) and allow dynamic link ids.
Signed-off-by: default avatarKarsten Graul <kgraul@linux.ibm.com>
Reviewed-by: default avatarUrsula Braun <ubraun@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 387707fd
...@@ -338,28 +338,48 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc) ...@@ -338,28 +338,48 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc)
} }
/* register a new rmb, send confirm_rkey msg to register with peer */ /* register a new rmb, send confirm_rkey msg to register with peer */
static int smc_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc, static int smcr_link_reg_rmb(struct smc_link *link,
bool conf_rkey) struct smc_buf_desc *rmb_desc, bool conf_rkey)
{ {
if (!rmb_desc->wr_reg) { if (!rmb_desc->is_reg_mr[link->link_idx]) {
/* register memory region for new rmb */ /* register memory region for new rmb */
if (smc_wr_reg_send(link, rmb_desc->mr_rx[link->link_idx])) { if (smc_wr_reg_send(link, rmb_desc->mr_rx[link->link_idx])) {
rmb_desc->regerr = 1; rmb_desc->is_reg_err = true;
return -EFAULT; return -EFAULT;
} }
rmb_desc->wr_reg = 1; rmb_desc->is_reg_mr[link->link_idx] = true;
} }
if (!conf_rkey) if (!conf_rkey)
return 0; return 0;
/* exchange confirm_rkey msg with peer */ /* exchange confirm_rkey msg with peer */
if (smc_llc_do_confirm_rkey(link, rmb_desc)) { if (!rmb_desc->is_conf_rkey) {
rmb_desc->regerr = 1; if (smc_llc_do_confirm_rkey(link, rmb_desc)) {
return -EFAULT; rmb_desc->is_reg_err = true;
return -EFAULT;
}
rmb_desc->is_conf_rkey = true;
}
return 0;
}
/* register the new rmb on all links */
static int smcr_lgr_reg_rmbs(struct smc_link_group *lgr,
struct smc_buf_desc *rmb_desc)
{
int i, rc;
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
if (lgr->lnk[i].state != SMC_LNK_ACTIVE)
continue;
rc = smcr_link_reg_rmb(&lgr->lnk[i], rmb_desc, true);
if (rc)
return rc;
} }
return 0; return 0;
} }
static int smc_clnt_conf_first_link(struct smc_sock *smc) static int smcr_clnt_conf_first_link(struct smc_sock *smc)
{ {
struct net *net = sock_net(smc->clcsock->sk); struct net *net = sock_net(smc->clcsock->sk);
struct smc_link *link = smc->conn.lnk; struct smc_link *link = smc->conn.lnk;
...@@ -387,7 +407,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc) ...@@ -387,7 +407,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
smc_wr_remember_qp_attr(link); smc_wr_remember_qp_attr(link);
if (smc_reg_rmb(link, smc->conn.rmb_desc, false)) if (smcr_link_reg_rmb(link, smc->conn.rmb_desc, false))
return SMC_CLC_DECL_ERR_REGRMB; return SMC_CLC_DECL_ERR_REGRMB;
/* send CONFIRM LINK response over RoCE fabric */ /* send CONFIRM LINK response over RoCE fabric */
...@@ -632,7 +652,7 @@ static int smc_connect_rdma(struct smc_sock *smc, ...@@ -632,7 +652,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
return smc_connect_abort(smc, SMC_CLC_DECL_ERR_RDYLNK, return smc_connect_abort(smc, SMC_CLC_DECL_ERR_RDYLNK,
ini->cln_first_contact); ini->cln_first_contact);
} else { } else {
if (smc_reg_rmb(link, smc->conn.rmb_desc, true)) if (smcr_lgr_reg_rmbs(smc->conn.lgr, smc->conn.rmb_desc))
return smc_connect_abort(smc, SMC_CLC_DECL_ERR_REGRMB, return smc_connect_abort(smc, SMC_CLC_DECL_ERR_REGRMB,
ini->cln_first_contact); ini->cln_first_contact);
} }
...@@ -647,7 +667,7 @@ static int smc_connect_rdma(struct smc_sock *smc, ...@@ -647,7 +667,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
if (ini->cln_first_contact == SMC_FIRST_CONTACT) { if (ini->cln_first_contact == SMC_FIRST_CONTACT) {
/* QP confirmation over RoCE fabric */ /* QP confirmation over RoCE fabric */
reason_code = smc_clnt_conf_first_link(smc); reason_code = smcr_clnt_conf_first_link(smc);
if (reason_code) if (reason_code)
return smc_connect_abort(smc, reason_code, return smc_connect_abort(smc, reason_code,
ini->cln_first_contact); ini->cln_first_contact);
...@@ -997,14 +1017,14 @@ void smc_close_non_accepted(struct sock *sk) ...@@ -997,14 +1017,14 @@ void smc_close_non_accepted(struct sock *sk)
sock_put(sk); /* final sock_put */ sock_put(sk); /* final sock_put */
} }
static int smc_serv_conf_first_link(struct smc_sock *smc) static int smcr_serv_conf_first_link(struct smc_sock *smc)
{ {
struct net *net = sock_net(smc->clcsock->sk); struct net *net = sock_net(smc->clcsock->sk);
struct smc_link *link = smc->conn.lnk; struct smc_link *link = smc->conn.lnk;
int rest; int rest;
int rc; int rc;
if (smc_reg_rmb(link, smc->conn.rmb_desc, false)) if (smcr_link_reg_rmb(link, smc->conn.rmb_desc, false))
return SMC_CLC_DECL_ERR_REGRMB; return SMC_CLC_DECL_ERR_REGRMB;
/* send CONFIRM LINK request to client over the RoCE fabric */ /* send CONFIRM LINK request to client over the RoCE fabric */
...@@ -1189,10 +1209,10 @@ static int smc_listen_ism_init(struct smc_sock *new_smc, ...@@ -1189,10 +1209,10 @@ static int smc_listen_ism_init(struct smc_sock *new_smc,
/* listen worker: register buffers */ /* listen worker: register buffers */
static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact) static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact)
{ {
struct smc_link *link = new_smc->conn.lnk; struct smc_connection *conn = &new_smc->conn;
if (local_contact != SMC_FIRST_CONTACT) { if (local_contact != SMC_FIRST_CONTACT) {
if (smc_reg_rmb(link, new_smc->conn.rmb_desc, true)) if (smcr_lgr_reg_rmbs(conn->lgr, conn->rmb_desc))
return SMC_CLC_DECL_ERR_REGRMB; return SMC_CLC_DECL_ERR_REGRMB;
} }
smc_rmb_sync_sg_for_device(&new_smc->conn); smc_rmb_sync_sg_for_device(&new_smc->conn);
...@@ -1222,7 +1242,7 @@ static int smc_listen_rdma_finish(struct smc_sock *new_smc, ...@@ -1222,7 +1242,7 @@ static int smc_listen_rdma_finish(struct smc_sock *new_smc,
goto decline; goto decline;
} }
/* QP confirmation over RoCE fabric */ /* QP confirmation over RoCE fabric */
reason_code = smc_serv_conf_first_link(new_smc); reason_code = smcr_serv_conf_first_link(new_smc);
if (reason_code) if (reason_code)
goto decline; goto decline;
} }
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */ #define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */
#define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/ #define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/
#define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */ #define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */
#define SMC_CLC_DECL_NOACTLINK 0x030a0000 /* no active smc-r link in lgr */
#define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */ #define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */
#define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */ #define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */
#define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */ #define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */
......
This diff is collapsed.
...@@ -152,25 +152,32 @@ struct smc_buf_desc { ...@@ -152,25 +152,32 @@ struct smc_buf_desc {
struct page *pages; struct page *pages;
int len; /* length of buffer */ int len; /* length of buffer */
u32 used; /* currently used / unused */ u32 used; /* currently used / unused */
u8 wr_reg : 1; /* mem region registered */
u8 regerr : 1; /* err during registration */
union { union {
struct { /* SMC-R */ struct { /* SMC-R */
struct sg_table sgt[SMC_LINKS_PER_LGR_MAX]; struct sg_table sgt[SMC_LINKS_PER_LGR_MAX];
/* virtual buffer */ /* virtual buffer */
struct ib_mr *mr_rx[SMC_LINKS_PER_LGR_MAX]; struct ib_mr *mr_rx[SMC_LINKS_PER_LGR_MAX];
/* for rmb only: memory region /* for rmb only: memory region
* incl. rkey provided to peer * incl. rkey provided to peer
*/ */
u32 order; /* allocation order */ u32 order; /* allocation order */
u8 is_conf_rkey;
/* confirm_rkey done */
u8 is_reg_mr[SMC_LINKS_PER_LGR_MAX];
/* mem region registered */
u8 is_map_ib[SMC_LINKS_PER_LGR_MAX];
/* mem region mapped to lnk */
u8 is_reg_err;
/* buffer registration err */
}; };
struct { /* SMC-D */ struct { /* SMC-D */
unsigned short sba_idx; unsigned short sba_idx;
/* SBA index number */ /* SBA index number */
u64 token; u64 token;
/* DMB token number */ /* DMB token number */
dma_addr_t dma_addr; dma_addr_t dma_addr;
/* DMA address */ /* DMA address */
}; };
}; };
}; };
......
...@@ -662,6 +662,8 @@ void smc_llc_link_deleting(struct smc_link *link) ...@@ -662,6 +662,8 @@ void smc_llc_link_deleting(struct smc_link *link)
/* called in tasklet context */ /* called in tasklet context */
void smc_llc_link_inactive(struct smc_link *link) void smc_llc_link_inactive(struct smc_link *link)
{ {
if (link->state == SMC_LNK_INACTIVE)
return;
link->state = SMC_LNK_INACTIVE; link->state = SMC_LNK_INACTIVE;
cancel_delayed_work(&link->llc_testlink_wrk); cancel_delayed_work(&link->llc_testlink_wrk);
smc_wr_wakeup_reg_wait(link); smc_wr_wakeup_reg_wait(link);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment