]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/smc/smc_close.c
net/smc: improve link group freeing
[mirror_ubuntu-jammy-kernel.git] / net / smc / smc_close.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
b38d7324
UB
2/*
3 * Shared Memory Communications over RDMA (SMC-R) and RoCE
4 *
5 * Socket Closing - normal and abnormal
6 *
7 * Copyright IBM Corp. 2016
8 *
9 * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com>
10 */
11
12#include <linux/workqueue.h>
c3edc401
IM
13#include <linux/sched/signal.h>
14
b38d7324
UB
15#include <net/sock.h>
16
17#include "smc.h"
18#include "smc_tx.h"
19#include "smc_cdc.h"
20#include "smc_close.h"
21
127f4970
UB
22#define SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME (5 * HZ)
23
fd57770d
KG
24/* release the clcsock that is assigned to the smc_sock */
25void smc_clcsock_release(struct smc_sock *smc)
26{
27 struct socket *tcp;
28
29 if (smc->listen_smc && current_work() != &smc->smc_listen_work)
30 cancel_work_sync(&smc->smc_listen_work);
31 mutex_lock(&smc->clcsock_release_lock);
32 if (smc->clcsock) {
33 tcp = smc->clcsock;
34 smc->clcsock = NULL;
35 sock_release(tcp);
36 }
37 mutex_unlock(&smc->clcsock_release_lock);
38}
39
b38d7324
UB
40static void smc_close_cleanup_listen(struct sock *parent)
41{
42 struct sock *sk;
43
44 /* Close non-accepted connections */
45 while ((sk = smc_accept_dequeue(parent, NULL)))
46 smc_close_non_accepted(sk);
47}
48
b38d7324
UB
49/* wait for sndbuf data being transmitted */
50static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
51{
52 DEFINE_WAIT_FUNC(wait, woken_wake_function);
53 struct sock *sk = &smc->sk;
54
55 if (!timeout)
56 return;
57
58 if (!smc_tx_prepared_sends(&smc->conn))
59 return;
60
61 smc->wait_close_tx_prepared = 1;
62 add_wait_queue(sk_sleep(sk), &wait);
63 while (!signal_pending(current) && timeout) {
64 int rc;
65
66 rc = sk_wait_event(sk, &timeout,
67 !smc_tx_prepared_sends(&smc->conn) ||
d18963cf 68 sk->sk_err == ECONNABORTED ||
b2900980
UB
69 sk->sk_err == ECONNRESET ||
70 smc->conn.killed,
b38d7324
UB
71 &wait);
72 if (rc)
73 break;
74 }
75 remove_wait_queue(sk_sleep(sk), &wait);
76 smc->wait_close_tx_prepared = 0;
77}
78
79void smc_close_wake_tx_prepared(struct smc_sock *smc)
80{
81 if (smc->wait_close_tx_prepared)
82 /* wake up socket closing */
83 smc->sk.sk_state_change(&smc->sk);
84}
85
86static int smc_close_wr(struct smc_connection *conn)
87{
88 conn->local_tx_ctrl.conn_state_flags.peer_done_writing = 1;
89
90 return smc_cdc_get_slot_and_msg_send(conn);
91}
92
93static int smc_close_final(struct smc_connection *conn)
94{
95 if (atomic_read(&conn->bytes_to_rcv))
96 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
97 else
98 conn->local_tx_ctrl.conn_state_flags.peer_conn_closed = 1;
b2900980
UB
99 if (conn->killed)
100 return -EPIPE;
b38d7324
UB
101
102 return smc_cdc_get_slot_and_msg_send(conn);
103}
104
105static int smc_close_abort(struct smc_connection *conn)
106{
107 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
108
109 return smc_cdc_get_slot_and_msg_send(conn);
110}
111
112/* terminate smc socket abnormally - active abort
732720fa 113 * link group is terminated, i.e. RDMA communication no longer possible
b38d7324 114 */
a8ae890b 115static void smc_close_active_abort(struct smc_sock *smc)
b38d7324 116{
3163c507
UB
117 struct sock *sk = &smc->sk;
118
dd65d87a
UB
119 if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
120 sk->sk_err = ECONNABORTED;
121 if (smc->clcsock && smc->clcsock->sk) {
122 smc->clcsock->sk->sk_err = ECONNABORTED;
123 smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
124 }
b38d7324 125 }
3163c507 126 switch (sk->sk_state) {
46c28dbd 127 case SMC_ACTIVE:
3163c507 128 sk->sk_state = SMC_PEERABORTWAIT;
611b63a1
UB
129 release_sock(sk);
130 cancel_delayed_work_sync(&smc->conn.tx_work);
131 lock_sock(sk);
d18963cf 132 sk->sk_state = SMC_CLOSED;
51f1de79 133 sock_put(sk); /* passive closing */
b38d7324
UB
134 break;
135 case SMC_APPCLOSEWAIT1:
136 case SMC_APPCLOSEWAIT2:
611b63a1
UB
137 release_sock(sk);
138 cancel_delayed_work_sync(&smc->conn.tx_work);
139 lock_sock(sk);
d18963cf 140 sk->sk_state = SMC_CLOSED;
b38d7324
UB
141 break;
142 case SMC_PEERCLOSEWAIT1:
143 case SMC_PEERCLOSEWAIT2:
d18963cf
UB
144 case SMC_PEERFINCLOSEWAIT:
145 sk->sk_state = SMC_CLOSED;
51f1de79 146 sock_put(sk); /* passive closing */
b38d7324
UB
147 break;
148 case SMC_PROCESSABORT:
149 case SMC_APPFINCLOSEWAIT:
3163c507 150 sk->sk_state = SMC_CLOSED;
b38d7324 151 break;
dd65d87a 152 case SMC_INIT:
b38d7324
UB
153 case SMC_PEERABORTWAIT:
154 case SMC_CLOSED:
155 break;
156 }
157
3163c507
UB
158 sock_set_flag(sk, SOCK_DEAD);
159 sk->sk_state_change(sk);
b38d7324
UB
160}
161
a98bf8c0
UB
162static inline bool smc_close_sent_any_close(struct smc_connection *conn)
163{
164 return conn->local_tx_ctrl.conn_state_flags.peer_conn_abort ||
165 conn->local_tx_ctrl.conn_state_flags.peer_conn_closed;
166}
167
b38d7324
UB
168int smc_close_active(struct smc_sock *smc)
169{
170 struct smc_cdc_conn_state_flags *txflags =
171 &smc->conn.local_tx_ctrl.conn_state_flags;
b38d7324
UB
172 struct smc_connection *conn = &smc->conn;
173 struct sock *sk = &smc->sk;
174 int old_state;
8c96feee 175 long timeout;
b38d7324
UB
176 int rc = 0;
177
8c96feee
UB
178 timeout = current->flags & PF_EXITING ?
179 0 : sock_flag(sk, SOCK_LINGER) ?
180 sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
b38d7324 181
b38d7324 182 old_state = sk->sk_state;
bbb96bf2
UB
183again:
184 switch (sk->sk_state) {
b38d7324
UB
185 case SMC_INIT:
186 sk->sk_state = SMC_CLOSED;
b38d7324
UB
187 break;
188 case SMC_LISTEN:
189 sk->sk_state = SMC_CLOSED;
190 sk->sk_state_change(sk); /* wake up accept */
191 if (smc->clcsock && smc->clcsock->sk) {
192 rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
193 /* wake up kernel_accept of smc_tcp_listen_worker */
194 smc->clcsock->sk->sk_data_ready(smc->clcsock->sk);
195 }
b38d7324 196 smc_close_cleanup_listen(sk);
3d502067
UB
197 release_sock(sk);
198 flush_work(&smc->tcp_listen_work);
199 lock_sock(sk);
b38d7324
UB
200 break;
201 case SMC_ACTIVE:
202 smc_close_stream_wait(smc, timeout);
203 release_sock(sk);
18e537cd 204 cancel_delayed_work_sync(&conn->tx_work);
b38d7324
UB
205 lock_sock(sk);
206 if (sk->sk_state == SMC_ACTIVE) {
207 /* send close request */
208 rc = smc_close_final(conn);
209 sk->sk_state = SMC_PEERCLOSEWAIT1;
210 } else {
211 /* peer event has changed the state */
212 goto again;
213 }
214 break;
215 case SMC_APPFINCLOSEWAIT:
216 /* socket already shutdown wr or both (active close) */
217 if (txflags->peer_done_writing &&
a98bf8c0 218 !smc_close_sent_any_close(conn)) {
b38d7324
UB
219 /* just shutdown wr done, send close request */
220 rc = smc_close_final(conn);
221 }
222 sk->sk_state = SMC_CLOSED;
b38d7324
UB
223 break;
224 case SMC_APPCLOSEWAIT1:
225 case SMC_APPCLOSEWAIT2:
226 if (!smc_cdc_rxed_any_close(conn))
227 smc_close_stream_wait(smc, timeout);
228 release_sock(sk);
18e537cd 229 cancel_delayed_work_sync(&conn->tx_work);
b38d7324 230 lock_sock(sk);
bbb96bf2
UB
231 if (sk->sk_state != SMC_APPCLOSEWAIT1 &&
232 sk->sk_state != SMC_APPCLOSEWAIT2)
233 goto again;
234 /* confirm close from peer */
235 rc = smc_close_final(conn);
51f1de79 236 if (smc_cdc_rxed_any_close(conn)) {
b38d7324
UB
237 /* peer has closed the socket already */
238 sk->sk_state = SMC_CLOSED;
51f1de79
UB
239 sock_put(sk); /* postponed passive closing */
240 } else {
b38d7324
UB
241 /* peer has just issued a shutdown write */
242 sk->sk_state = SMC_PEERFINCLOSEWAIT;
51f1de79 243 }
b38d7324
UB
244 break;
245 case SMC_PEERCLOSEWAIT1:
246 case SMC_PEERCLOSEWAIT2:
a98bf8c0
UB
247 if (txflags->peer_done_writing &&
248 !smc_close_sent_any_close(conn)) {
249 /* just shutdown wr done, send close request */
250 rc = smc_close_final(conn);
251 }
252 /* peer sending PeerConnectionClosed will cause transition */
253 break;
b38d7324
UB
254 case SMC_PEERFINCLOSEWAIT:
255 /* peer sending PeerConnectionClosed will cause transition */
256 break;
257 case SMC_PROCESSABORT:
d18963cf 258 rc = smc_close_abort(conn);
b38d7324 259 sk->sk_state = SMC_CLOSED;
b38d7324
UB
260 break;
261 case SMC_PEERABORTWAIT:
d18963cf
UB
262 sk->sk_state = SMC_CLOSED;
263 break;
b38d7324
UB
264 case SMC_CLOSED:
265 /* nothing to do, add tracing in future patch */
266 break;
267 }
268
269 if (old_state != sk->sk_state)
3163c507 270 sk->sk_state_change(sk);
b38d7324
UB
271 return rc;
272}
273
274static void smc_close_passive_abort_received(struct smc_sock *smc)
275{
276 struct smc_cdc_conn_state_flags *txflags =
277 &smc->conn.local_tx_ctrl.conn_state_flags;
278 struct sock *sk = &smc->sk;
279
280 switch (sk->sk_state) {
51f1de79 281 case SMC_INIT:
b38d7324 282 case SMC_ACTIVE:
b38d7324 283 case SMC_APPCLOSEWAIT1:
51f1de79
UB
284 sk->sk_state = SMC_PROCESSABORT;
285 sock_put(sk); /* passive closing */
286 break;
287 case SMC_APPFINCLOSEWAIT:
b38d7324
UB
288 sk->sk_state = SMC_PROCESSABORT;
289 break;
290 case SMC_PEERCLOSEWAIT1:
291 case SMC_PEERCLOSEWAIT2:
292 if (txflags->peer_done_writing &&
51f1de79 293 !smc_close_sent_any_close(&smc->conn))
b38d7324 294 /* just shutdown, but not yet closed locally */
b38d7324 295 sk->sk_state = SMC_PROCESSABORT;
51f1de79 296 else
b38d7324 297 sk->sk_state = SMC_CLOSED;
51f1de79 298 sock_put(sk); /* passive closing */
b38d7324 299 break;
51f1de79 300 case SMC_APPCLOSEWAIT2:
b38d7324 301 case SMC_PEERFINCLOSEWAIT:
51f1de79
UB
302 sk->sk_state = SMC_CLOSED;
303 sock_put(sk); /* passive closing */
304 break;
b38d7324
UB
305 case SMC_PEERABORTWAIT:
306 sk->sk_state = SMC_CLOSED;
307 break;
b38d7324
UB
308 case SMC_PROCESSABORT:
309 /* nothing to do, add tracing in future patch */
310 break;
311 }
312}
313
732720fa
UB
314/* Either some kind of closing has been received: peer_conn_closed,
315 * peer_conn_abort, or peer_done_writing
316 * or the link group of the connection terminates abnormally.
b38d7324 317 */
46c28dbd 318static void smc_close_passive_work(struct work_struct *work)
b38d7324 319{
46c28dbd
UB
320 struct smc_connection *conn = container_of(work,
321 struct smc_connection,
322 close_work);
323 struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
324 struct smc_cdc_conn_state_flags *rxflags;
fd57770d 325 bool release_clcsock = false;
b38d7324
UB
326 struct sock *sk = &smc->sk;
327 int old_state;
328
3163c507 329 lock_sock(sk);
b38d7324
UB
330 old_state = sk->sk_state;
331
b2900980 332 if (conn->killed) {
46c28dbd
UB
333 /* abnormal termination */
334 smc_close_active_abort(smc);
335 goto wakeup;
336 }
337
3163c507 338 rxflags = &conn->local_rx_ctrl.conn_state_flags;
b38d7324 339 if (rxflags->peer_conn_abort) {
732720fa 340 /* peer has not received all data */
b38d7324 341 smc_close_passive_abort_received(smc);
611b63a1
UB
342 release_sock(&smc->sk);
343 cancel_delayed_work_sync(&conn->tx_work);
344 lock_sock(&smc->sk);
b38d7324
UB
345 goto wakeup;
346 }
347
348 switch (sk->sk_state) {
349 case SMC_INIT:
84b799a2 350 sk->sk_state = SMC_APPCLOSEWAIT1;
b38d7324
UB
351 break;
352 case SMC_ACTIVE:
353 sk->sk_state = SMC_APPCLOSEWAIT1;
51f1de79
UB
354 /* postpone sock_put() for passive closing to cover
355 * received SEND_SHUTDOWN as well
356 */
b38d7324
UB
357 break;
358 case SMC_PEERCLOSEWAIT1:
359 if (rxflags->peer_done_writing)
360 sk->sk_state = SMC_PEERCLOSEWAIT2;
7f6b437e
GS
361 /* fall through */
362 /* to check for closing */
b38d7324 363 case SMC_PEERCLOSEWAIT2:
3163c507 364 if (!smc_cdc_rxed_any_close(conn))
b38d7324
UB
365 break;
366 if (sock_flag(sk, SOCK_DEAD) &&
a98bf8c0 367 smc_close_sent_any_close(conn)) {
b38d7324
UB
368 /* smc_release has already been called locally */
369 sk->sk_state = SMC_CLOSED;
370 } else {
371 /* just shutdown, but not yet closed locally */
372 sk->sk_state = SMC_APPFINCLOSEWAIT;
373 }
51f1de79 374 sock_put(sk); /* passive closing */
b38d7324 375 break;
5ac92a00 376 case SMC_PEERFINCLOSEWAIT:
51f1de79 377 if (smc_cdc_rxed_any_close(conn)) {
5ac92a00 378 sk->sk_state = SMC_CLOSED;
51f1de79
UB
379 sock_put(sk); /* passive closing */
380 }
5ac92a00 381 break;
b38d7324
UB
382 case SMC_APPCLOSEWAIT1:
383 case SMC_APPCLOSEWAIT2:
51f1de79
UB
384 /* postpone sock_put() for passive closing to cover
385 * received SEND_SHUTDOWN as well
386 */
387 break;
b38d7324
UB
388 case SMC_APPFINCLOSEWAIT:
389 case SMC_PEERABORTWAIT:
390 case SMC_PROCESSABORT:
391 case SMC_CLOSED:
392 /* nothing to do, add tracing in future patch */
393 break;
394 }
395
396wakeup:
b38d7324
UB
397 sk->sk_data_ready(sk); /* wakeup blocked rcvbuf consumers */
398 sk->sk_write_space(sk); /* wakeup blocked sndbuf producers */
399
a98bf8c0
UB
400 if (old_state != sk->sk_state) {
401 sk->sk_state_change(sk);
402 if ((sk->sk_state == SMC_CLOSED) &&
b03faa1f 403 (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
3163c507 404 smc_conn_free(conn);
fd57770d
KG
405 if (smc->clcsock)
406 release_clcsock = true;
b03faa1f 407 }
b38d7324 408 }
3163c507 409 release_sock(sk);
fd57770d
KG
410 if (release_clcsock)
411 smc_clcsock_release(smc);
51f1de79 412 sock_put(sk); /* sock_hold done by schedulers of close_work */
b38d7324
UB
413}
414
415int smc_close_shutdown_write(struct smc_sock *smc)
416{
417 struct smc_connection *conn = &smc->conn;
b38d7324
UB
418 struct sock *sk = &smc->sk;
419 int old_state;
8c96feee 420 long timeout;
b38d7324
UB
421 int rc = 0;
422
8c96feee
UB
423 timeout = current->flags & PF_EXITING ?
424 0 : sock_flag(sk, SOCK_LINGER) ?
425 sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
b38d7324 426
b38d7324 427 old_state = sk->sk_state;
bbb96bf2
UB
428again:
429 switch (sk->sk_state) {
b38d7324
UB
430 case SMC_ACTIVE:
431 smc_close_stream_wait(smc, timeout);
432 release_sock(sk);
18e537cd 433 cancel_delayed_work_sync(&conn->tx_work);
b38d7324 434 lock_sock(sk);
bbb96bf2
UB
435 if (sk->sk_state != SMC_ACTIVE)
436 goto again;
b38d7324
UB
437 /* send close wr request */
438 rc = smc_close_wr(conn);
bbb96bf2 439 sk->sk_state = SMC_PEERCLOSEWAIT1;
b38d7324
UB
440 break;
441 case SMC_APPCLOSEWAIT1:
442 /* passive close */
443 if (!smc_cdc_rxed_any_close(conn))
444 smc_close_stream_wait(smc, timeout);
445 release_sock(sk);
18e537cd 446 cancel_delayed_work_sync(&conn->tx_work);
b38d7324 447 lock_sock(sk);
bbb96bf2
UB
448 if (sk->sk_state != SMC_APPCLOSEWAIT1)
449 goto again;
b38d7324
UB
450 /* confirm close from peer */
451 rc = smc_close_wr(conn);
452 sk->sk_state = SMC_APPCLOSEWAIT2;
453 break;
454 case SMC_APPCLOSEWAIT2:
455 case SMC_PEERFINCLOSEWAIT:
456 case SMC_PEERCLOSEWAIT1:
457 case SMC_PEERCLOSEWAIT2:
458 case SMC_APPFINCLOSEWAIT:
459 case SMC_PROCESSABORT:
460 case SMC_PEERABORTWAIT:
461 /* nothing to do, add tracing in future patch */
462 break;
463 }
464
465 if (old_state != sk->sk_state)
3163c507 466 sk->sk_state_change(sk);
b38d7324
UB
467 return rc;
468}
46c28dbd
UB
469
470/* Initialize close properties on connection establishment. */
471void smc_close_init(struct smc_sock *smc)
472{
473 INIT_WORK(&smc->conn.close_work, smc_close_passive_work);
474}