Skip to content

Commit 127f497

Browse files
Ursula Braundavem330
authored andcommitted
net/smc: release clcsock from tcp_listen_worker
Closing a listen socket may hit the warning WARN_ON(sock_owned_by_user(sk)) of tcp_close(), if the wake up of the smc_tcp_listen_worker has not yet finished. This patch introduces smc_close_wait_listen_clcsock() making sure the listening internal clcsock has been closed in smc_tcp_listen_work(), before the listening external SMC socket finishes closing. Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 51f1de7 commit 127f497

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

net/smc/af_smc.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,10 @@ struct sock *smc_accept_dequeue(struct sock *parent,
670670

671671
smc_accept_unlink(new_sk);
672672
if (new_sk->sk_state == SMC_CLOSED) {
673+
if (isk->clcsock) {
674+
sock_release(isk->clcsock);
675+
isk->clcsock = NULL;
676+
}
673677
new_sk->sk_prot->unhash(new_sk);
674678
sock_put(new_sk); /* final */
675679
continue;
@@ -969,8 +973,15 @@ static void smc_tcp_listen_work(struct work_struct *work)
969973
}
970974

971975
out:
976+
if (lsmc->clcsock) {
977+
sock_release(lsmc->clcsock);
978+
lsmc->clcsock = NULL;
979+
}
972980
release_sock(lsk);
973-
lsk->sk_data_ready(lsk); /* no more listening, wake accept */
981+
/* no more listening, wake up smc_close_wait_listen_clcsock and
982+
* accept
983+
*/
984+
lsk->sk_state_change(lsk);
974985
sock_put(&lsmc->sk); /* sock_hold in smc_listen */
975986
}
976987

net/smc/smc_close.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "smc_cdc.h"
2020
#include "smc_close.h"
2121

22+
#define SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME (5 * HZ)
23+
2224
static void smc_close_cleanup_listen(struct sock *parent)
2325
{
2426
struct sock *sk;
@@ -28,6 +30,27 @@ static void smc_close_cleanup_listen(struct sock *parent)
2830
smc_close_non_accepted(sk);
2931
}
3032

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+
3154
/* wait for sndbuf data being transmitted */
3255
static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
3356
{
@@ -114,7 +137,6 @@ static void smc_close_active_abort(struct smc_sock *smc)
114137
break;
115138
case SMC_APPCLOSEWAIT1:
116139
case SMC_APPCLOSEWAIT2:
117-
sock_release(smc->clcsock);
118140
if (!smc_cdc_rxed_any_close(&smc->conn))
119141
sk->sk_state = SMC_PEERABORTWAIT;
120142
else
@@ -128,16 +150,13 @@ static void smc_close_active_abort(struct smc_sock *smc)
128150
if (!txflags->peer_conn_closed) {
129151
/* just SHUTDOWN_SEND done */
130152
sk->sk_state = SMC_PEERABORTWAIT;
131-
sock_release(smc->clcsock);
132153
} else {
133154
sk->sk_state = SMC_CLOSED;
134155
}
135156
sock_put(sk); /* passive closing */
136157
break;
137158
case SMC_PROCESSABORT:
138159
case SMC_APPFINCLOSEWAIT:
139-
if (!txflags->peer_conn_closed)
140-
sock_release(smc->clcsock);
141160
sk->sk_state = SMC_CLOSED;
142161
break;
143162
case SMC_PEERFINCLOSEWAIT:
@@ -177,8 +196,6 @@ int smc_close_active(struct smc_sock *smc)
177196
switch (sk->sk_state) {
178197
case SMC_INIT:
179198
sk->sk_state = SMC_CLOSED;
180-
if (smc->smc_listen_work.func)
181-
cancel_work_sync(&smc->smc_listen_work);
182199
break;
183200
case SMC_LISTEN:
184201
sk->sk_state = SMC_CLOSED;
@@ -187,11 +204,9 @@ int smc_close_active(struct smc_sock *smc)
187204
rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
188205
/* wake up kernel_accept of smc_tcp_listen_worker */
189206
smc->clcsock->sk->sk_data_ready(smc->clcsock->sk);
207+
smc_close_wait_listen_clcsock(smc);
190208
}
191-
release_sock(sk);
192209
smc_close_cleanup_listen(sk);
193-
cancel_work_sync(&smc->smc_listen_work);
194-
lock_sock(sk);
195210
break;
196211
case SMC_ACTIVE:
197212
smc_close_stream_wait(smc, timeout);

0 commit comments

Comments
 (0)