diff options
author | Ursula Braun <ubraun@linux.vnet.ibm.com> | 2018-03-13 05:41:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-15 09:49:13 -0400 |
commit | 3d502067599f0db12e74e6646aee8728efe3e5be (patch) | |
tree | 1db2e80c9656338b5edf75e163abcd3c9863dbdf | |
parent | cf55612a945039476abfd73e39064b2e721c3272 (diff) |
net/smc: simplify wait when closing listen socket
Closing of a listen socket wakes up kernel_accept() of
smc_tcp_listen_worker(), and then has to wait till smc_tcp_listen_worker()
gives up the internal clcsock. The wait logic introduced with
commit 127f49705823 ("net/smc: release clcsock from tcp_listen_worker")
might wait longer than necessary. This patch implements the idea to
implement the wait just with flush_work(), and gets rid of the extra
smc_close_wait_listen_clcsock() function.
Fixes: 127f49705823 ("net/smc: release clcsock from tcp_listen_worker")
Reported-by: Hans Wippel <hwippel@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/smc/af_smc.c | 4 | ||||
-rw-r--r-- | net/smc/smc_close.c | 25 |
2 files changed, 3 insertions, 26 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 8cc97834d4f6..1e0d780855c3 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
@@ -978,10 +978,6 @@ out: | |||
978 | lsmc->clcsock = NULL; | 978 | lsmc->clcsock = NULL; |
979 | } | 979 | } |
980 | release_sock(lsk); | 980 | release_sock(lsk); |
981 | /* no more listening, wake up smc_close_wait_listen_clcsock and | ||
982 | * accept | ||
983 | */ | ||
984 | lsk->sk_state_change(lsk); | ||
985 | sock_put(&lsmc->sk); /* sock_hold in smc_listen */ | 981 | sock_put(&lsmc->sk); /* sock_hold in smc_listen */ |
986 | } | 982 | } |
987 | 983 | ||
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index e339c0186dcf..fa41d9881741 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c | |||
@@ -30,27 +30,6 @@ static void smc_close_cleanup_listen(struct sock *parent) | |||
30 | smc_close_non_accepted(sk); | 30 | smc_close_non_accepted(sk); |
31 | } | 31 | } |
32 | 32 | ||
33 | static void smc_close_wait_listen_clcsock(struct smc_sock *smc) | ||
34 | { | ||
35 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||
36 | struct sock *sk = &smc->sk; | ||
37 | signed long timeout; | ||
38 | |||
39 | timeout = SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME; | ||
40 | add_wait_queue(sk_sleep(sk), &wait); | ||
41 | do { | ||
42 | release_sock(sk); | ||
43 | if (smc->clcsock) | ||
44 | timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE, | ||
45 | timeout); | ||
46 | sched_annotate_sleep(); | ||
47 | lock_sock(sk); | ||
48 | if (!smc->clcsock) | ||
49 | break; | ||
50 | } while (timeout); | ||
51 | remove_wait_queue(sk_sleep(sk), &wait); | ||
52 | } | ||
53 | |||
54 | /* wait for sndbuf data being transmitted */ | 33 | /* wait for sndbuf data being transmitted */ |
55 | static void smc_close_stream_wait(struct smc_sock *smc, long timeout) | 34 | static void smc_close_stream_wait(struct smc_sock *smc, long timeout) |
56 | { | 35 | { |
@@ -204,9 +183,11 @@ again: | |||
204 | rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); | 183 | rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); |
205 | /* wake up kernel_accept of smc_tcp_listen_worker */ | 184 | /* wake up kernel_accept of smc_tcp_listen_worker */ |
206 | smc->clcsock->sk->sk_data_ready(smc->clcsock->sk); | 185 | smc->clcsock->sk->sk_data_ready(smc->clcsock->sk); |
207 | smc_close_wait_listen_clcsock(smc); | ||
208 | } | 186 | } |
209 | smc_close_cleanup_listen(sk); | 187 | smc_close_cleanup_listen(sk); |
188 | release_sock(sk); | ||
189 | flush_work(&smc->tcp_listen_work); | ||
190 | lock_sock(sk); | ||
210 | break; | 191 | break; |
211 | case SMC_ACTIVE: | 192 | case SMC_ACTIVE: |
212 | smc_close_stream_wait(smc, timeout); | 193 | smc_close_stream_wait(smc, timeout); |