diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-16 15:08:18 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-16 15:12:00 -0400 |
commit | 89982f7ccee2fcd8fea7936b81eec6defbf0f131 (patch) | |
tree | fc553c8d008d24595ad7de0ea0f3b56f656da27c /net/smc | |
parent | a1ceeca679dccc492235f0f629d9e9f7b3d51ca8 (diff) | |
parent | 94710cac0ef4ee177a63b5227664b38c95bbf703 (diff) |
Merge tag 'v4.18' into rdma.git for-next
Resolve merge conflicts from the -rc cycle against the rdma.git tree:
Conflicts:
drivers/infiniband/core/uverbs_cmd.c
- New ifs added to ib_uverbs_ex_create_flow in -rc and for-next
- Merge removal of file->ucontext in for-next with new code in -rc
drivers/infiniband/core/uverbs_main.c
- for-next removed code from ib_uverbs_write() that was modified
in for-rc
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'net/smc')
-rw-r--r-- | net/smc/af_smc.c | 151 | ||||
-rw-r--r-- | net/smc/smc.h | 8 | ||||
-rw-r--r-- | net/smc/smc_cdc.c | 3 | ||||
-rw-r--r-- | net/smc/smc_clc.c | 3 | ||||
-rw-r--r-- | net/smc/smc_close.c | 2 | ||||
-rw-r--r-- | net/smc/smc_tx.c | 12 |
6 files changed, 129 insertions, 50 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index da7f02edcd37..e7de5f282722 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
@@ -45,6 +45,7 @@ static DEFINE_MUTEX(smc_create_lgr_pending); /* serialize link group | |||
45 | */ | 45 | */ |
46 | 46 | ||
47 | static void smc_tcp_listen_work(struct work_struct *); | 47 | static void smc_tcp_listen_work(struct work_struct *); |
48 | static void smc_connect_work(struct work_struct *); | ||
48 | 49 | ||
49 | static void smc_set_keepalive(struct sock *sk, int val) | 50 | static void smc_set_keepalive(struct sock *sk, int val) |
50 | { | 51 | { |
@@ -122,6 +123,12 @@ static int smc_release(struct socket *sock) | |||
122 | goto out; | 123 | goto out; |
123 | 124 | ||
124 | smc = smc_sk(sk); | 125 | smc = smc_sk(sk); |
126 | |||
127 | /* cleanup for a dangling non-blocking connect */ | ||
128 | flush_work(&smc->connect_work); | ||
129 | kfree(smc->connect_info); | ||
130 | smc->connect_info = NULL; | ||
131 | |||
125 | if (sk->sk_state == SMC_LISTEN) | 132 | if (sk->sk_state == SMC_LISTEN) |
126 | /* smc_close_non_accepted() is called and acquires | 133 | /* smc_close_non_accepted() is called and acquires |
127 | * sock lock for child sockets again | 134 | * sock lock for child sockets again |
@@ -140,7 +147,8 @@ static int smc_release(struct socket *sock) | |||
140 | smc->clcsock = NULL; | 147 | smc->clcsock = NULL; |
141 | } | 148 | } |
142 | if (smc->use_fallback) { | 149 | if (smc->use_fallback) { |
143 | sock_put(sk); /* passive closing */ | 150 | if (sk->sk_state != SMC_LISTEN && sk->sk_state != SMC_INIT) |
151 | sock_put(sk); /* passive closing */ | ||
144 | sk->sk_state = SMC_CLOSED; | 152 | sk->sk_state = SMC_CLOSED; |
145 | sk->sk_state_change(sk); | 153 | sk->sk_state_change(sk); |
146 | } | 154 | } |
@@ -186,6 +194,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock, | |||
186 | sk->sk_protocol = protocol; | 194 | sk->sk_protocol = protocol; |
187 | smc = smc_sk(sk); | 195 | smc = smc_sk(sk); |
188 | INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work); | 196 | INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work); |
197 | INIT_WORK(&smc->connect_work, smc_connect_work); | ||
189 | INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work); | 198 | INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work); |
190 | INIT_LIST_HEAD(&smc->accept_q); | 199 | INIT_LIST_HEAD(&smc->accept_q); |
191 | spin_lock_init(&smc->accept_q_lock); | 200 | spin_lock_init(&smc->accept_q_lock); |
@@ -409,12 +418,18 @@ static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code) | |||
409 | { | 418 | { |
410 | int rc; | 419 | int rc; |
411 | 420 | ||
412 | if (reason_code < 0) /* error, fallback is not possible */ | 421 | if (reason_code < 0) { /* error, fallback is not possible */ |
422 | if (smc->sk.sk_state == SMC_INIT) | ||
423 | sock_put(&smc->sk); /* passive closing */ | ||
413 | return reason_code; | 424 | return reason_code; |
425 | } | ||
414 | if (reason_code != SMC_CLC_DECL_REPLY) { | 426 | if (reason_code != SMC_CLC_DECL_REPLY) { |
415 | rc = smc_clc_send_decline(smc, reason_code); | 427 | rc = smc_clc_send_decline(smc, reason_code); |
416 | if (rc < 0) | 428 | if (rc < 0) { |
429 | if (smc->sk.sk_state == SMC_INIT) | ||
430 | sock_put(&smc->sk); /* passive closing */ | ||
417 | return rc; | 431 | return rc; |
432 | } | ||
418 | } | 433 | } |
419 | return smc_connect_fallback(smc); | 434 | return smc_connect_fallback(smc); |
420 | } | 435 | } |
@@ -427,8 +442,6 @@ static int smc_connect_abort(struct smc_sock *smc, int reason_code, | |||
427 | smc_lgr_forget(smc->conn.lgr); | 442 | smc_lgr_forget(smc->conn.lgr); |
428 | mutex_unlock(&smc_create_lgr_pending); | 443 | mutex_unlock(&smc_create_lgr_pending); |
429 | smc_conn_free(&smc->conn); | 444 | smc_conn_free(&smc->conn); |
430 | if (reason_code < 0 && smc->sk.sk_state == SMC_INIT) | ||
431 | sock_put(&smc->sk); /* passive closing */ | ||
432 | return reason_code; | 445 | return reason_code; |
433 | } | 446 | } |
434 | 447 | ||
@@ -576,6 +589,35 @@ static int __smc_connect(struct smc_sock *smc) | |||
576 | return 0; | 589 | return 0; |
577 | } | 590 | } |
578 | 591 | ||
592 | static void smc_connect_work(struct work_struct *work) | ||
593 | { | ||
594 | struct smc_sock *smc = container_of(work, struct smc_sock, | ||
595 | connect_work); | ||
596 | int rc; | ||
597 | |||
598 | lock_sock(&smc->sk); | ||
599 | rc = kernel_connect(smc->clcsock, &smc->connect_info->addr, | ||
600 | smc->connect_info->alen, smc->connect_info->flags); | ||
601 | if (smc->clcsock->sk->sk_err) { | ||
602 | smc->sk.sk_err = smc->clcsock->sk->sk_err; | ||
603 | goto out; | ||
604 | } | ||
605 | if (rc < 0) { | ||
606 | smc->sk.sk_err = -rc; | ||
607 | goto out; | ||
608 | } | ||
609 | |||
610 | rc = __smc_connect(smc); | ||
611 | if (rc < 0) | ||
612 | smc->sk.sk_err = -rc; | ||
613 | |||
614 | out: | ||
615 | smc->sk.sk_state_change(&smc->sk); | ||
616 | kfree(smc->connect_info); | ||
617 | smc->connect_info = NULL; | ||
618 | release_sock(&smc->sk); | ||
619 | } | ||
620 | |||
579 | static int smc_connect(struct socket *sock, struct sockaddr *addr, | 621 | static int smc_connect(struct socket *sock, struct sockaddr *addr, |
580 | int alen, int flags) | 622 | int alen, int flags) |
581 | { | 623 | { |
@@ -605,15 +647,32 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr, | |||
605 | 647 | ||
606 | smc_copy_sock_settings_to_clc(smc); | 648 | smc_copy_sock_settings_to_clc(smc); |
607 | tcp_sk(smc->clcsock->sk)->syn_smc = 1; | 649 | tcp_sk(smc->clcsock->sk)->syn_smc = 1; |
608 | rc = kernel_connect(smc->clcsock, addr, alen, flags); | 650 | if (flags & O_NONBLOCK) { |
609 | if (rc) | 651 | if (smc->connect_info) { |
610 | goto out; | 652 | rc = -EALREADY; |
653 | goto out; | ||
654 | } | ||
655 | smc->connect_info = kzalloc(alen + 2 * sizeof(int), GFP_KERNEL); | ||
656 | if (!smc->connect_info) { | ||
657 | rc = -ENOMEM; | ||
658 | goto out; | ||
659 | } | ||
660 | smc->connect_info->alen = alen; | ||
661 | smc->connect_info->flags = flags ^ O_NONBLOCK; | ||
662 | memcpy(&smc->connect_info->addr, addr, alen); | ||
663 | schedule_work(&smc->connect_work); | ||
664 | rc = -EINPROGRESS; | ||
665 | } else { | ||
666 | rc = kernel_connect(smc->clcsock, addr, alen, flags); | ||
667 | if (rc) | ||
668 | goto out; | ||
611 | 669 | ||
612 | rc = __smc_connect(smc); | 670 | rc = __smc_connect(smc); |
613 | if (rc < 0) | 671 | if (rc < 0) |
614 | goto out; | 672 | goto out; |
615 | else | 673 | else |
616 | rc = 0; /* success cases including fallback */ | 674 | rc = 0; /* success cases including fallback */ |
675 | } | ||
617 | 676 | ||
618 | out: | 677 | out: |
619 | release_sock(sk); | 678 | release_sock(sk); |
@@ -1063,6 +1122,8 @@ static void smc_tcp_listen_work(struct work_struct *work) | |||
1063 | sock_hold(lsk); /* sock_put in smc_listen_work */ | 1122 | sock_hold(lsk); /* sock_put in smc_listen_work */ |
1064 | INIT_WORK(&new_smc->smc_listen_work, smc_listen_work); | 1123 | INIT_WORK(&new_smc->smc_listen_work, smc_listen_work); |
1065 | smc_copy_sock_settings_to_smc(new_smc); | 1124 | smc_copy_sock_settings_to_smc(new_smc); |
1125 | new_smc->sk.sk_sndbuf = lsmc->sk.sk_sndbuf; | ||
1126 | new_smc->sk.sk_rcvbuf = lsmc->sk.sk_rcvbuf; | ||
1066 | sock_hold(&new_smc->sk); /* sock_put in passive closing */ | 1127 | sock_hold(&new_smc->sk); /* sock_put in passive closing */ |
1067 | if (!schedule_work(&new_smc->smc_listen_work)) | 1128 | if (!schedule_work(&new_smc->smc_listen_work)) |
1068 | sock_put(&new_smc->sk); | 1129 | sock_put(&new_smc->sk); |
@@ -1273,40 +1334,26 @@ static __poll_t smc_accept_poll(struct sock *parent) | |||
1273 | return mask; | 1334 | return mask; |
1274 | } | 1335 | } |
1275 | 1336 | ||
1276 | static __poll_t smc_poll_mask(struct socket *sock, __poll_t events) | 1337 | static __poll_t smc_poll(struct file *file, struct socket *sock, |
1338 | poll_table *wait) | ||
1277 | { | 1339 | { |
1278 | struct sock *sk = sock->sk; | 1340 | struct sock *sk = sock->sk; |
1279 | __poll_t mask = 0; | 1341 | __poll_t mask = 0; |
1280 | struct smc_sock *smc; | 1342 | struct smc_sock *smc; |
1281 | int rc; | ||
1282 | 1343 | ||
1283 | if (!sk) | 1344 | if (!sk) |
1284 | return EPOLLNVAL; | 1345 | return EPOLLNVAL; |
1285 | 1346 | ||
1286 | smc = smc_sk(sock->sk); | 1347 | smc = smc_sk(sock->sk); |
1287 | sock_hold(sk); | ||
1288 | lock_sock(sk); | ||
1289 | if ((sk->sk_state == SMC_INIT) || smc->use_fallback) { | 1348 | if ((sk->sk_state == SMC_INIT) || smc->use_fallback) { |
1290 | /* delegate to CLC child sock */ | 1349 | /* delegate to CLC child sock */ |
1291 | release_sock(sk); | 1350 | mask = smc->clcsock->ops->poll(file, smc->clcsock, wait); |
1292 | mask = smc->clcsock->ops->poll_mask(smc->clcsock, events); | ||
1293 | lock_sock(sk); | ||
1294 | sk->sk_err = smc->clcsock->sk->sk_err; | 1351 | sk->sk_err = smc->clcsock->sk->sk_err; |
1295 | if (sk->sk_err) { | 1352 | if (sk->sk_err) |
1296 | mask |= EPOLLERR; | 1353 | mask |= EPOLLERR; |
1297 | } else { | ||
1298 | /* if non-blocking connect finished ... */ | ||
1299 | if (sk->sk_state == SMC_INIT && | ||
1300 | mask & EPOLLOUT && | ||
1301 | smc->clcsock->sk->sk_state != TCP_CLOSE) { | ||
1302 | rc = __smc_connect(smc); | ||
1303 | if (rc < 0) | ||
1304 | mask |= EPOLLERR; | ||
1305 | /* success cases including fallback */ | ||
1306 | mask |= EPOLLOUT | EPOLLWRNORM; | ||
1307 | } | ||
1308 | } | ||
1309 | } else { | 1354 | } else { |
1355 | if (sk->sk_state != SMC_CLOSED) | ||
1356 | sock_poll_wait(file, sk_sleep(sk), wait); | ||
1310 | if (sk->sk_err) | 1357 | if (sk->sk_err) |
1311 | mask |= EPOLLERR; | 1358 | mask |= EPOLLERR; |
1312 | if ((sk->sk_shutdown == SHUTDOWN_MASK) || | 1359 | if ((sk->sk_shutdown == SHUTDOWN_MASK) || |
@@ -1332,10 +1379,7 @@ static __poll_t smc_poll_mask(struct socket *sock, __poll_t events) | |||
1332 | } | 1379 | } |
1333 | if (smc->conn.urg_state == SMC_URG_VALID) | 1380 | if (smc->conn.urg_state == SMC_URG_VALID) |
1334 | mask |= EPOLLPRI; | 1381 | mask |= EPOLLPRI; |
1335 | |||
1336 | } | 1382 | } |
1337 | release_sock(sk); | ||
1338 | sock_put(sk); | ||
1339 | 1383 | ||
1340 | return mask; | 1384 | return mask; |
1341 | } | 1385 | } |
@@ -1355,8 +1399,7 @@ static int smc_shutdown(struct socket *sock, int how) | |||
1355 | lock_sock(sk); | 1399 | lock_sock(sk); |
1356 | 1400 | ||
1357 | rc = -ENOTCONN; | 1401 | rc = -ENOTCONN; |
1358 | if ((sk->sk_state != SMC_LISTEN) && | 1402 | if ((sk->sk_state != SMC_ACTIVE) && |
1359 | (sk->sk_state != SMC_ACTIVE) && | ||
1360 | (sk->sk_state != SMC_PEERCLOSEWAIT1) && | 1403 | (sk->sk_state != SMC_PEERCLOSEWAIT1) && |
1361 | (sk->sk_state != SMC_PEERCLOSEWAIT2) && | 1404 | (sk->sk_state != SMC_PEERCLOSEWAIT2) && |
1362 | (sk->sk_state != SMC_APPCLOSEWAIT1) && | 1405 | (sk->sk_state != SMC_APPCLOSEWAIT1) && |
@@ -1415,7 +1458,8 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, | |||
1415 | 1458 | ||
1416 | if (optlen < sizeof(int)) | 1459 | if (optlen < sizeof(int)) |
1417 | return -EINVAL; | 1460 | return -EINVAL; |
1418 | get_user(val, (int __user *)optval); | 1461 | if (get_user(val, (int __user *)optval)) |
1462 | return -EFAULT; | ||
1419 | 1463 | ||
1420 | lock_sock(sk); | 1464 | lock_sock(sk); |
1421 | switch (optname) { | 1465 | switch (optname) { |
@@ -1478,15 +1522,22 @@ static int smc_ioctl(struct socket *sock, unsigned int cmd, | |||
1478 | 1522 | ||
1479 | smc = smc_sk(sock->sk); | 1523 | smc = smc_sk(sock->sk); |
1480 | conn = &smc->conn; | 1524 | conn = &smc->conn; |
1525 | lock_sock(&smc->sk); | ||
1481 | if (smc->use_fallback) { | 1526 | if (smc->use_fallback) { |
1482 | if (!smc->clcsock) | 1527 | if (!smc->clcsock) { |
1528 | release_sock(&smc->sk); | ||
1483 | return -EBADF; | 1529 | return -EBADF; |
1484 | return smc->clcsock->ops->ioctl(smc->clcsock, cmd, arg); | 1530 | } |
1531 | answ = smc->clcsock->ops->ioctl(smc->clcsock, cmd, arg); | ||
1532 | release_sock(&smc->sk); | ||
1533 | return answ; | ||
1485 | } | 1534 | } |
1486 | switch (cmd) { | 1535 | switch (cmd) { |
1487 | case SIOCINQ: /* same as FIONREAD */ | 1536 | case SIOCINQ: /* same as FIONREAD */ |
1488 | if (smc->sk.sk_state == SMC_LISTEN) | 1537 | if (smc->sk.sk_state == SMC_LISTEN) { |
1538 | release_sock(&smc->sk); | ||
1489 | return -EINVAL; | 1539 | return -EINVAL; |
1540 | } | ||
1490 | if (smc->sk.sk_state == SMC_INIT || | 1541 | if (smc->sk.sk_state == SMC_INIT || |
1491 | smc->sk.sk_state == SMC_CLOSED) | 1542 | smc->sk.sk_state == SMC_CLOSED) |
1492 | answ = 0; | 1543 | answ = 0; |
@@ -1495,8 +1546,10 @@ static int smc_ioctl(struct socket *sock, unsigned int cmd, | |||
1495 | break; | 1546 | break; |
1496 | case SIOCOUTQ: | 1547 | case SIOCOUTQ: |
1497 | /* output queue size (not send + not acked) */ | 1548 | /* output queue size (not send + not acked) */ |
1498 | if (smc->sk.sk_state == SMC_LISTEN) | 1549 | if (smc->sk.sk_state == SMC_LISTEN) { |
1550 | release_sock(&smc->sk); | ||
1499 | return -EINVAL; | 1551 | return -EINVAL; |
1552 | } | ||
1500 | if (smc->sk.sk_state == SMC_INIT || | 1553 | if (smc->sk.sk_state == SMC_INIT || |
1501 | smc->sk.sk_state == SMC_CLOSED) | 1554 | smc->sk.sk_state == SMC_CLOSED) |
1502 | answ = 0; | 1555 | answ = 0; |
@@ -1506,8 +1559,10 @@ static int smc_ioctl(struct socket *sock, unsigned int cmd, | |||
1506 | break; | 1559 | break; |
1507 | case SIOCOUTQNSD: | 1560 | case SIOCOUTQNSD: |
1508 | /* output queue size (not send only) */ | 1561 | /* output queue size (not send only) */ |
1509 | if (smc->sk.sk_state == SMC_LISTEN) | 1562 | if (smc->sk.sk_state == SMC_LISTEN) { |
1563 | release_sock(&smc->sk); | ||
1510 | return -EINVAL; | 1564 | return -EINVAL; |
1565 | } | ||
1511 | if (smc->sk.sk_state == SMC_INIT || | 1566 | if (smc->sk.sk_state == SMC_INIT || |
1512 | smc->sk.sk_state == SMC_CLOSED) | 1567 | smc->sk.sk_state == SMC_CLOSED) |
1513 | answ = 0; | 1568 | answ = 0; |
@@ -1515,8 +1570,10 @@ static int smc_ioctl(struct socket *sock, unsigned int cmd, | |||
1515 | answ = smc_tx_prepared_sends(&smc->conn); | 1570 | answ = smc_tx_prepared_sends(&smc->conn); |
1516 | break; | 1571 | break; |
1517 | case SIOCATMARK: | 1572 | case SIOCATMARK: |
1518 | if (smc->sk.sk_state == SMC_LISTEN) | 1573 | if (smc->sk.sk_state == SMC_LISTEN) { |
1574 | release_sock(&smc->sk); | ||
1519 | return -EINVAL; | 1575 | return -EINVAL; |
1576 | } | ||
1520 | if (smc->sk.sk_state == SMC_INIT || | 1577 | if (smc->sk.sk_state == SMC_INIT || |
1521 | smc->sk.sk_state == SMC_CLOSED) { | 1578 | smc->sk.sk_state == SMC_CLOSED) { |
1522 | answ = 0; | 1579 | answ = 0; |
@@ -1532,8 +1589,10 @@ static int smc_ioctl(struct socket *sock, unsigned int cmd, | |||
1532 | } | 1589 | } |
1533 | break; | 1590 | break; |
1534 | default: | 1591 | default: |
1592 | release_sock(&smc->sk); | ||
1535 | return -ENOIOCTLCMD; | 1593 | return -ENOIOCTLCMD; |
1536 | } | 1594 | } |
1595 | release_sock(&smc->sk); | ||
1537 | 1596 | ||
1538 | return put_user(answ, (int __user *)arg); | 1597 | return put_user(answ, (int __user *)arg); |
1539 | } | 1598 | } |
@@ -1619,7 +1678,7 @@ static const struct proto_ops smc_sock_ops = { | |||
1619 | .socketpair = sock_no_socketpair, | 1678 | .socketpair = sock_no_socketpair, |
1620 | .accept = smc_accept, | 1679 | .accept = smc_accept, |
1621 | .getname = smc_getname, | 1680 | .getname = smc_getname, |
1622 | .poll_mask = smc_poll_mask, | 1681 | .poll = smc_poll, |
1623 | .ioctl = smc_ioctl, | 1682 | .ioctl = smc_ioctl, |
1624 | .listen = smc_listen, | 1683 | .listen = smc_listen, |
1625 | .shutdown = smc_shutdown, | 1684 | .shutdown = smc_shutdown, |
diff --git a/net/smc/smc.h b/net/smc/smc.h index 51ae1f10d81a..d7ca26570482 100644 --- a/net/smc/smc.h +++ b/net/smc/smc.h | |||
@@ -187,11 +187,19 @@ struct smc_connection { | |||
187 | struct work_struct close_work; /* peer sent some closing */ | 187 | struct work_struct close_work; /* peer sent some closing */ |
188 | }; | 188 | }; |
189 | 189 | ||
190 | struct smc_connect_info { | ||
191 | int flags; | ||
192 | int alen; | ||
193 | struct sockaddr addr; | ||
194 | }; | ||
195 | |||
190 | struct smc_sock { /* smc sock container */ | 196 | struct smc_sock { /* smc sock container */ |
191 | struct sock sk; | 197 | struct sock sk; |
192 | struct socket *clcsock; /* internal tcp socket */ | 198 | struct socket *clcsock; /* internal tcp socket */ |
193 | struct smc_connection conn; /* smc connection */ | 199 | struct smc_connection conn; /* smc connection */ |
194 | struct smc_sock *listen_smc; /* listen parent */ | 200 | struct smc_sock *listen_smc; /* listen parent */ |
201 | struct smc_connect_info *connect_info; /* connect address & flags */ | ||
202 | struct work_struct connect_work; /* handle non-blocking connect*/ | ||
195 | struct work_struct tcp_listen_work;/* handle tcp socket accepts */ | 203 | struct work_struct tcp_listen_work;/* handle tcp socket accepts */ |
196 | struct work_struct smc_listen_work;/* prepare new accept socket */ | 204 | struct work_struct smc_listen_work;/* prepare new accept socket */ |
197 | struct list_head accept_q; /* sockets to be accepted */ | 205 | struct list_head accept_q; /* sockets to be accepted */ |
diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c index a7e8d63fc8ae..9bde1e4ca288 100644 --- a/net/smc/smc_cdc.c +++ b/net/smc/smc_cdc.c | |||
@@ -233,7 +233,8 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc, | |||
233 | /* force immediate tx of current consumer cursor, but | 233 | /* force immediate tx of current consumer cursor, but |
234 | * under send_lock to guarantee arrival in seqno-order | 234 | * under send_lock to guarantee arrival in seqno-order |
235 | */ | 235 | */ |
236 | smc_tx_sndbuf_nonempty(conn); | 236 | if (smc->sk.sk_state != SMC_INIT) |
237 | smc_tx_sndbuf_nonempty(conn); | ||
237 | } | 238 | } |
238 | } | 239 | } |
239 | 240 | ||
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 717449b1da0b..ae5d168653ce 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c | |||
@@ -250,6 +250,7 @@ out: | |||
250 | int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, | 250 | int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, |
251 | u8 expected_type) | 251 | u8 expected_type) |
252 | { | 252 | { |
253 | long rcvtimeo = smc->clcsock->sk->sk_rcvtimeo; | ||
253 | struct sock *clc_sk = smc->clcsock->sk; | 254 | struct sock *clc_sk = smc->clcsock->sk; |
254 | struct smc_clc_msg_hdr *clcm = buf; | 255 | struct smc_clc_msg_hdr *clcm = buf; |
255 | struct msghdr msg = {NULL, 0}; | 256 | struct msghdr msg = {NULL, 0}; |
@@ -306,7 +307,6 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, | |||
306 | memset(&msg, 0, sizeof(struct msghdr)); | 307 | memset(&msg, 0, sizeof(struct msghdr)); |
307 | iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, datlen); | 308 | iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, datlen); |
308 | krflags = MSG_WAITALL; | 309 | krflags = MSG_WAITALL; |
309 | smc->clcsock->sk->sk_rcvtimeo = CLC_WAIT_TIME; | ||
310 | len = sock_recvmsg(smc->clcsock, &msg, krflags); | 310 | len = sock_recvmsg(smc->clcsock, &msg, krflags); |
311 | if (len < datlen || !smc_clc_msg_hdr_valid(clcm)) { | 311 | if (len < datlen || !smc_clc_msg_hdr_valid(clcm)) { |
312 | smc->sk.sk_err = EPROTO; | 312 | smc->sk.sk_err = EPROTO; |
@@ -322,6 +322,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, | |||
322 | } | 322 | } |
323 | 323 | ||
324 | out: | 324 | out: |
325 | smc->clcsock->sk->sk_rcvtimeo = rcvtimeo; | ||
325 | return reason_code; | 326 | return reason_code; |
326 | } | 327 | } |
327 | 328 | ||
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index fa41d9881741..ac961dfb1ea1 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c | |||
@@ -107,6 +107,8 @@ static void smc_close_active_abort(struct smc_sock *smc) | |||
107 | } | 107 | } |
108 | switch (sk->sk_state) { | 108 | switch (sk->sk_state) { |
109 | case SMC_INIT: | 109 | case SMC_INIT: |
110 | sk->sk_state = SMC_PEERABORTWAIT; | ||
111 | break; | ||
110 | case SMC_ACTIVE: | 112 | case SMC_ACTIVE: |
111 | sk->sk_state = SMC_PEERABORTWAIT; | 113 | sk->sk_state = SMC_PEERABORTWAIT; |
112 | release_sock(sk); | 114 | release_sock(sk); |
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c index a171c168f98e..72e1a2782fe8 100644 --- a/net/smc/smc_tx.c +++ b/net/smc/smc_tx.c | |||
@@ -494,7 +494,8 @@ out: | |||
494 | 494 | ||
495 | void smc_tx_consumer_update(struct smc_connection *conn, bool force) | 495 | void smc_tx_consumer_update(struct smc_connection *conn, bool force) |
496 | { | 496 | { |
497 | union smc_host_cursor cfed, cons; | 497 | union smc_host_cursor cfed, cons, prod; |
498 | int sender_free = conn->rmb_desc->len; | ||
498 | int to_confirm; | 499 | int to_confirm; |
499 | 500 | ||
500 | smc_curs_write(&cons, | 501 | smc_curs_write(&cons, |
@@ -504,11 +505,18 @@ void smc_tx_consumer_update(struct smc_connection *conn, bool force) | |||
504 | smc_curs_read(&conn->rx_curs_confirmed, conn), | 505 | smc_curs_read(&conn->rx_curs_confirmed, conn), |
505 | conn); | 506 | conn); |
506 | to_confirm = smc_curs_diff(conn->rmb_desc->len, &cfed, &cons); | 507 | to_confirm = smc_curs_diff(conn->rmb_desc->len, &cfed, &cons); |
508 | if (to_confirm > conn->rmbe_update_limit) { | ||
509 | smc_curs_write(&prod, | ||
510 | smc_curs_read(&conn->local_rx_ctrl.prod, conn), | ||
511 | conn); | ||
512 | sender_free = conn->rmb_desc->len - | ||
513 | smc_curs_diff(conn->rmb_desc->len, &prod, &cfed); | ||
514 | } | ||
507 | 515 | ||
508 | if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req || | 516 | if (conn->local_rx_ctrl.prod_flags.cons_curs_upd_req || |
509 | force || | 517 | force || |
510 | ((to_confirm > conn->rmbe_update_limit) && | 518 | ((to_confirm > conn->rmbe_update_limit) && |
511 | ((to_confirm > (conn->rmb_desc->len / 2)) || | 519 | ((sender_free <= (conn->rmb_desc->len / 2)) || |
512 | conn->local_rx_ctrl.prod_flags.write_blocked))) { | 520 | conn->local_rx_ctrl.prod_flags.write_blocked))) { |
513 | if ((smc_cdc_get_slot_and_msg_send(conn) < 0) && | 521 | if ((smc_cdc_get_slot_and_msg_send(conn) < 0) && |
514 | conn->alert_token_local) { /* connection healthy */ | 522 | conn->alert_token_local) { /* connection healthy */ |