aboutsummaryrefslogtreecommitdiffstats
path: root/net/smc/smc_close.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/smc/smc_close.c')
-rw-r--r--net/smc/smc_close.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 2427a1f3d0d1..5cda681e5cc4 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -180,6 +180,7 @@ int smc_close_active(struct smc_sock *smc)
int old_state;
long timeout;
int rc = 0;
+ int rc1 = 0;
timeout = current->flags & PF_EXITING ?
0 : sock_flag(sk, SOCK_LINGER) ?
@@ -215,6 +216,15 @@ again:
/* send close request */
rc = smc_close_final(conn);
sk->sk_state = SMC_PEERCLOSEWAIT1;
+
+ /* actively shutdown clcsock before peer close it,
+ * prevent peer from entering TIME_WAIT state.
+ */
+ if (smc->clcsock && smc->clcsock->sk) {
+ rc1 = kernel_sock_shutdown(smc->clcsock,
+ SHUT_RDWR);
+ rc = rc ? rc : rc1;
+ }
} else {
/* peer event has changed the state */
goto again;