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

net/smc: unregister rkeys of unused buffer

When an rmb is no longer in use by a connection, unregister its rkey at
the remote peer with an LLC DELETE RKEY message. With this change,
unused buffers held in the buffer pool are no longer registered at the
remote peer. They are registered before the buffer is actually used and
unregistered when they are no longer used by a connection.
Signed-off-by: default avatarKarsten Graul <kgraul@linux.ibm.com>
Signed-off-by: default avatarUrsula Braun <ubraun@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 60e03c62
...@@ -299,14 +299,17 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc) ...@@ -299,14 +299,17 @@ 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); smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC);
} }
/* register a new rmb, optionally 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 smc_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc,
bool conf_rkey) bool conf_rkey)
{ {
/* register memory region for new rmb */ if (!rmb_desc->wr_reg) {
if (smc_wr_reg_send(link, rmb_desc->mr_rx[SMC_SINGLE_LINK])) { /* register memory region for new rmb */
rmb_desc->regerr = 1; if (smc_wr_reg_send(link, rmb_desc->mr_rx[SMC_SINGLE_LINK])) {
return -EFAULT; rmb_desc->regerr = 1;
return -EFAULT;
}
rmb_desc->wr_reg = 1;
} }
if (!conf_rkey) if (!conf_rkey)
return 0; return 0;
...@@ -581,8 +584,7 @@ static int smc_connect_rdma(struct smc_sock *smc, ...@@ -581,8 +584,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,
local_contact); local_contact);
} else { } else {
if (!smc->conn.rmb_desc->reused && if (smc_reg_rmb(link, smc->conn.rmb_desc, true))
smc_reg_rmb(link, smc->conn.rmb_desc, true))
return smc_connect_abort(smc, SMC_CLC_DECL_ERR_REGRMB, return smc_connect_abort(smc, SMC_CLC_DECL_ERR_REGRMB,
local_contact); local_contact);
} }
...@@ -1143,10 +1145,8 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact) ...@@ -1143,10 +1145,8 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact)
struct smc_link *link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK]; struct smc_link *link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK];
if (local_contact != SMC_FIRST_CONTACT) { if (local_contact != SMC_FIRST_CONTACT) {
if (!new_smc->conn.rmb_desc->reused) { if (smc_reg_rmb(link, new_smc->conn.rmb_desc, true))
if (smc_reg_rmb(link, new_smc->conn.rmb_desc, true)) 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);
......
...@@ -298,8 +298,13 @@ static void smc_buf_unuse(struct smc_connection *conn, ...@@ -298,8 +298,13 @@ static void smc_buf_unuse(struct smc_connection *conn,
conn->sndbuf_desc->used = 0; conn->sndbuf_desc->used = 0;
if (conn->rmb_desc) { if (conn->rmb_desc) {
if (!conn->rmb_desc->regerr) { if (!conn->rmb_desc->regerr) {
conn->rmb_desc->reused = 1;
conn->rmb_desc->used = 0; conn->rmb_desc->used = 0;
if (!lgr->is_smcd) {
/* unregister rmb with peer */
smc_llc_do_delete_rkey(
&lgr->lnk[SMC_SINGLE_LINK],
conn->rmb_desc);
}
} else { } else {
/* buf registration failed, reuse not possible */ /* buf registration failed, reuse not possible */
write_lock_bh(&lgr->rmbs_lock); write_lock_bh(&lgr->rmbs_lock);
......
...@@ -130,7 +130,7 @@ struct smc_buf_desc { ...@@ -130,7 +130,7 @@ 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 reused : 1; /* new created / reused */ u8 wr_reg : 1; /* mem region registered */
u8 regerr : 1; /* err during registration */ u8 regerr : 1; /* err during registration */
union { union {
struct { /* SMC-R */ struct { /* SMC-R */
......
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