Commit 3d502067 authored by Ursula Braun's avatar Ursula Braun Committed by David S. Miller

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 127f4970 ("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: 127f4970 ("net/smc: release clcsock from tcp_listen_worker")
Reported-by: default avatarHans Wippel <hwippel@linux.vnet.ibm.com>
Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cf55612a
...@@ -978,10 +978,6 @@ static void smc_tcp_listen_work(struct work_struct *work) ...@@ -978,10 +978,6 @@ static void smc_tcp_listen_work(struct work_struct *work)
lsmc->clcsock = NULL; lsmc->clcsock = NULL;
} }
release_sock(lsk); release_sock(lsk);
/* no more listening, wake up smc_close_wait_listen_clcsock and
* accept
*/
lsk->sk_state_change(lsk);
sock_put(&lsmc->sk); /* sock_hold in smc_listen */ sock_put(&lsmc->sk); /* sock_hold in smc_listen */
} }
......
...@@ -30,27 +30,6 @@ static void smc_close_cleanup_listen(struct sock *parent) ...@@ -30,27 +30,6 @@ static void smc_close_cleanup_listen(struct sock *parent)
smc_close_non_accepted(sk); smc_close_non_accepted(sk);
} }
static void smc_close_wait_listen_clcsock(struct smc_sock *smc)
{
DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = &smc->sk;
signed long timeout;
timeout = SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME;
add_wait_queue(sk_sleep(sk), &wait);
do {
release_sock(sk);
if (smc->clcsock)
timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE,
timeout);
sched_annotate_sleep();
lock_sock(sk);
if (!smc->clcsock)
break;
} while (timeout);
remove_wait_queue(sk_sleep(sk), &wait);
}
/* wait for sndbuf data being transmitted */ /* wait for sndbuf data being transmitted */
static void smc_close_stream_wait(struct smc_sock *smc, long timeout) static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
{ {
...@@ -204,9 +183,11 @@ int smc_close_active(struct smc_sock *smc) ...@@ -204,9 +183,11 @@ int smc_close_active(struct smc_sock *smc)
rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
/* wake up kernel_accept of smc_tcp_listen_worker */ /* wake up kernel_accept of smc_tcp_listen_worker */
smc->clcsock->sk->sk_data_ready(smc->clcsock->sk); smc->clcsock->sk->sk_data_ready(smc->clcsock->sk);
smc_close_wait_listen_clcsock(smc);
} }
smc_close_cleanup_listen(sk); smc_close_cleanup_listen(sk);
release_sock(sk);
flush_work(&smc->tcp_listen_work);
lock_sock(sk);
break; break;
case SMC_ACTIVE: case SMC_ACTIVE:
smc_close_stream_wait(smc, timeout); smc_close_stream_wait(smc, timeout);
......
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