aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-05-03 14:47:32 -0400
committerDavid S. Miller <davem@davemloft.net>2018-05-03 14:47:32 -0400
commit31140b47fe4b90ea38f29a48214e76d8b7f64176 (patch)
tree886341f8a24668c1f8a4a7c813f0404e9bb72187
parentdf80b8fb3c0ef510649d2d6e350cf11be240d15c (diff)
parentbda27ff5c4526f80a7620a94ecfe8dca153e3696 (diff)
Merge branch 'smc-fixes'
Ursula Braun says: ==================== net/smc: fixes 2018/05/03 here are smc fixes for 2 problems: * receive buffers in SMC must be registered. If registration fails these buffers must not be kept within the link group for reuse. Patch 1 is a preparational patch; patch 2 contains the fix. * sendpage: do not hold the sock lock when calling kernel_sendpage() or sock_no_sendpage() ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/smc/af_smc.c43
-rw-r--r--net/smc/smc_core.c22
-rw-r--r--net/smc/smc_core.h3
3 files changed, 42 insertions, 26 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 8b4c059bd13b..544bab42f925 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -292,6 +292,17 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc)
292 smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC); 292 smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC);
293} 293}
294 294
295/* register a new rmb */
296static int smc_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc)
297{
298 /* register memory region for new rmb */
299 if (smc_wr_reg_send(link, rmb_desc->mr_rx[SMC_SINGLE_LINK])) {
300 rmb_desc->regerr = 1;
301 return -EFAULT;
302 }
303 return 0;
304}
305
295static int smc_clnt_conf_first_link(struct smc_sock *smc) 306static int smc_clnt_conf_first_link(struct smc_sock *smc)
296{ 307{
297 struct smc_link_group *lgr = smc->conn.lgr; 308 struct smc_link_group *lgr = smc->conn.lgr;
@@ -321,9 +332,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
321 332
322 smc_wr_remember_qp_attr(link); 333 smc_wr_remember_qp_attr(link);
323 334
324 rc = smc_wr_reg_send(link, 335 if (smc_reg_rmb(link, smc->conn.rmb_desc))
325 smc->conn.rmb_desc->mr_rx[SMC_SINGLE_LINK]);
326 if (rc)
327 return SMC_CLC_DECL_INTERR; 336 return SMC_CLC_DECL_INTERR;
328 337
329 /* send CONFIRM LINK response over RoCE fabric */ 338 /* send CONFIRM LINK response over RoCE fabric */
@@ -473,13 +482,8 @@ static int smc_connect_rdma(struct smc_sock *smc)
473 goto decline_rdma_unlock; 482 goto decline_rdma_unlock;
474 } 483 }
475 } else { 484 } else {
476 struct smc_buf_desc *buf_desc = smc->conn.rmb_desc; 485 if (!smc->conn.rmb_desc->reused) {
477 486 if (smc_reg_rmb(link, smc->conn.rmb_desc)) {
478 if (!buf_desc->reused) {
479 /* register memory region for new rmb */
480 rc = smc_wr_reg_send(link,
481 buf_desc->mr_rx[SMC_SINGLE_LINK]);
482 if (rc) {
483 reason_code = SMC_CLC_DECL_INTERR; 487 reason_code = SMC_CLC_DECL_INTERR;
484 goto decline_rdma_unlock; 488 goto decline_rdma_unlock;
485 } 489 }
@@ -719,9 +723,7 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
719 723
720 link = &lgr->lnk[SMC_SINGLE_LINK]; 724 link = &lgr->lnk[SMC_SINGLE_LINK];
721 725
722 rc = smc_wr_reg_send(link, 726 if (smc_reg_rmb(link, smc->conn.rmb_desc))
723 smc->conn.rmb_desc->mr_rx[SMC_SINGLE_LINK]);
724 if (rc)
725 return SMC_CLC_DECL_INTERR; 727 return SMC_CLC_DECL_INTERR;
726 728
727 /* send CONFIRM LINK request to client over the RoCE fabric */ 729 /* send CONFIRM LINK request to client over the RoCE fabric */
@@ -854,13 +856,8 @@ static void smc_listen_work(struct work_struct *work)
854 smc_rx_init(new_smc); 856 smc_rx_init(new_smc);
855 857
856 if (local_contact != SMC_FIRST_CONTACT) { 858 if (local_contact != SMC_FIRST_CONTACT) {
857 struct smc_buf_desc *buf_desc = new_smc->conn.rmb_desc; 859 if (!new_smc->conn.rmb_desc->reused) {
858 860 if (smc_reg_rmb(link, new_smc->conn.rmb_desc)) {
859 if (!buf_desc->reused) {
860 /* register memory region for new rmb */
861 rc = smc_wr_reg_send(link,
862 buf_desc->mr_rx[SMC_SINGLE_LINK]);
863 if (rc) {
864 reason_code = SMC_CLC_DECL_INTERR; 861 reason_code = SMC_CLC_DECL_INTERR;
865 goto decline_rdma_unlock; 862 goto decline_rdma_unlock;
866 } 863 }
@@ -1318,8 +1315,11 @@ static ssize_t smc_sendpage(struct socket *sock, struct page *page,
1318 1315
1319 smc = smc_sk(sk); 1316 smc = smc_sk(sk);
1320 lock_sock(sk); 1317 lock_sock(sk);
1321 if (sk->sk_state != SMC_ACTIVE) 1318 if (sk->sk_state != SMC_ACTIVE) {
1319 release_sock(sk);
1322 goto out; 1320 goto out;
1321 }
1322 release_sock(sk);
1323 if (smc->use_fallback) 1323 if (smc->use_fallback)
1324 rc = kernel_sendpage(smc->clcsock, page, offset, 1324 rc = kernel_sendpage(smc->clcsock, page, offset,
1325 size, flags); 1325 size, flags);
@@ -1327,7 +1327,6 @@ static ssize_t smc_sendpage(struct socket *sock, struct page *page,
1327 rc = sock_no_sendpage(sock, page, offset, size, flags); 1327 rc = sock_no_sendpage(sock, page, offset, size, flags);
1328 1328
1329out: 1329out:
1330 release_sock(sk);
1331 return rc; 1330 return rc;
1332} 1331}
1333 1332
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index f44f6803f7ff..d4bd01bb44e1 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -32,6 +32,9 @@
32 32
33static u32 smc_lgr_num; /* unique link group number */ 33static u32 smc_lgr_num; /* unique link group number */
34 34
35static void smc_buf_free(struct smc_buf_desc *buf_desc, struct smc_link *lnk,
36 bool is_rmb);
37
35static void smc_lgr_schedule_free_work(struct smc_link_group *lgr) 38static void smc_lgr_schedule_free_work(struct smc_link_group *lgr)
36{ 39{
37 /* client link group creation always follows the server link group 40 /* client link group creation always follows the server link group
@@ -234,9 +237,22 @@ static void smc_buf_unuse(struct smc_connection *conn)
234 conn->sndbuf_size = 0; 237 conn->sndbuf_size = 0;
235 } 238 }
236 if (conn->rmb_desc) { 239 if (conn->rmb_desc) {
237 conn->rmb_desc->reused = true; 240 if (!conn->rmb_desc->regerr) {
238 conn->rmb_desc->used = 0; 241 conn->rmb_desc->reused = 1;
239 conn->rmbe_size = 0; 242 conn->rmb_desc->used = 0;
243 conn->rmbe_size = 0;
244 } else {
245 /* buf registration failed, reuse not possible */
246 struct smc_link_group *lgr = conn->lgr;
247 struct smc_link *lnk;
248
249 write_lock_bh(&lgr->rmbs_lock);
250 list_del(&conn->rmb_desc->list);
251 write_unlock_bh(&lgr->rmbs_lock);
252
253 lnk = &lgr->lnk[SMC_SINGLE_LINK];
254 smc_buf_free(conn->rmb_desc, lnk, true);
255 }
240 } 256 }
241} 257}
242 258
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index 07e2a393e6d9..5dfcb15d529f 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -123,7 +123,8 @@ struct smc_buf_desc {
123 */ 123 */
124 u32 order; /* allocation order */ 124 u32 order; /* allocation order */
125 u32 used; /* currently used / unused */ 125 u32 used; /* currently used / unused */
126 bool reused; /* new created / reused */ 126 u8 reused : 1; /* new created / reused */
127 u8 regerr : 1; /* err during registration */
127}; 128};
128 129
129struct smc_rtoken { /* address/key of remote RMB */ 130struct smc_rtoken { /* address/key of remote RMB */