1
2
3
4
5
6
7
8
9
10
11
12#include <linux/workqueue.h>
13#include <linux/sched/signal.h>
14
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
22#define SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME (5 * HZ)
23
24static void smc_close_cleanup_listen(struct sock *parent)
25{
26 struct sock *sk;
27
28
29 while ((sk = smc_accept_dequeue(parent, NULL)))
30 smc_close_non_accepted(sk);
31}
32
33
34static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
35{
36 DEFINE_WAIT_FUNC(wait, woken_wake_function);
37 struct sock *sk = &smc->sk;
38
39 if (!timeout)
40 return;
41
42 if (!smc_tx_prepared_sends(&smc->conn))
43 return;
44
45 smc->wait_close_tx_prepared = 1;
46 add_wait_queue(sk_sleep(sk), &wait);
47 while (!signal_pending(current) && timeout) {
48 int rc;
49
50 rc = sk_wait_event(sk, &timeout,
51 !smc_tx_prepared_sends(&smc->conn) ||
52 (sk->sk_err == ECONNABORTED) ||
53 (sk->sk_err == ECONNRESET),
54 &wait);
55 if (rc)
56 break;
57 }
58 remove_wait_queue(sk_sleep(sk), &wait);
59 smc->wait_close_tx_prepared = 0;
60}
61
62void smc_close_wake_tx_prepared(struct smc_sock *smc)
63{
64 if (smc->wait_close_tx_prepared)
65
66 smc->sk.sk_state_change(&smc->sk);
67}
68
69static int smc_close_wr(struct smc_connection *conn)
70{
71 conn->local_tx_ctrl.conn_state_flags.peer_done_writing = 1;
72
73 return smc_cdc_get_slot_and_msg_send(conn);
74}
75
76static int smc_close_final(struct smc_connection *conn)
77{
78 if (atomic_read(&conn->bytes_to_rcv))
79 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
80 else
81 conn->local_tx_ctrl.conn_state_flags.peer_conn_closed = 1;
82
83 return smc_cdc_get_slot_and_msg_send(conn);
84}
85
86static int smc_close_abort(struct smc_connection *conn)
87{
88 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
89
90 return smc_cdc_get_slot_and_msg_send(conn);
91}
92
93
94
95
96static void smc_close_active_abort(struct smc_sock *smc)
97{
98 struct sock *sk = &smc->sk;
99
100 struct smc_cdc_conn_state_flags *txflags =
101 &smc->conn.local_tx_ctrl.conn_state_flags;
102
103 sk->sk_err = ECONNABORTED;
104 if (smc->clcsock && smc->clcsock->sk) {
105 smc->clcsock->sk->sk_err = ECONNABORTED;
106 smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
107 }
108 switch (sk->sk_state) {
109 case SMC_INIT:
110 case SMC_ACTIVE:
111 sk->sk_state = SMC_PEERABORTWAIT;
112 release_sock(sk);
113 cancel_delayed_work_sync(&smc->conn.tx_work);
114 lock_sock(sk);
115 sock_put(sk);
116 break;
117 case SMC_APPCLOSEWAIT1:
118 case SMC_APPCLOSEWAIT2:
119 if (!smc_cdc_rxed_any_close(&smc->conn))
120 sk->sk_state = SMC_PEERABORTWAIT;
121 else
122 sk->sk_state = SMC_CLOSED;
123 release_sock(sk);
124 cancel_delayed_work_sync(&smc->conn.tx_work);
125 lock_sock(sk);
126 break;
127 case SMC_PEERCLOSEWAIT1:
128 case SMC_PEERCLOSEWAIT2:
129 if (!txflags->peer_conn_closed) {
130
131 sk->sk_state = SMC_PEERABORTWAIT;
132 } else {
133 sk->sk_state = SMC_CLOSED;
134 }
135 sock_put(sk);
136 break;
137 case SMC_PROCESSABORT:
138 case SMC_APPFINCLOSEWAIT:
139 sk->sk_state = SMC_CLOSED;
140 break;
141 case SMC_PEERFINCLOSEWAIT:
142 sock_put(sk);
143 break;
144 case SMC_PEERABORTWAIT:
145 case SMC_CLOSED:
146 break;
147 }
148
149 sock_set_flag(sk, SOCK_DEAD);
150 sk->sk_state_change(sk);
151}
152
153static inline bool smc_close_sent_any_close(struct smc_connection *conn)
154{
155 return conn->local_tx_ctrl.conn_state_flags.peer_conn_abort ||
156 conn->local_tx_ctrl.conn_state_flags.peer_conn_closed;
157}
158
159int smc_close_active(struct smc_sock *smc)
160{
161 struct smc_cdc_conn_state_flags *txflags =
162 &smc->conn.local_tx_ctrl.conn_state_flags;
163 struct smc_connection *conn = &smc->conn;
164 struct sock *sk = &smc->sk;
165 int old_state;
166 long timeout;
167 int rc = 0;
168
169 timeout = current->flags & PF_EXITING ?
170 0 : sock_flag(sk, SOCK_LINGER) ?
171 sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
172
173 old_state = sk->sk_state;
174again:
175 switch (sk->sk_state) {
176 case SMC_INIT:
177 sk->sk_state = SMC_CLOSED;
178 break;
179 case SMC_LISTEN:
180 sk->sk_state = SMC_CLOSED;
181 sk->sk_state_change(sk);
182 if (smc->clcsock && smc->clcsock->sk) {
183 rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
184
185 smc->clcsock->sk->sk_data_ready(smc->clcsock->sk);
186 }
187 smc_close_cleanup_listen(sk);
188 release_sock(sk);
189 flush_work(&smc->tcp_listen_work);
190 lock_sock(sk);
191 break;
192 case SMC_ACTIVE:
193 smc_close_stream_wait(smc, timeout);
194 release_sock(sk);
195 cancel_delayed_work_sync(&conn->tx_work);
196 lock_sock(sk);
197 if (sk->sk_state == SMC_ACTIVE) {
198
199 rc = smc_close_final(conn);
200 if (rc)
201 break;
202 sk->sk_state = SMC_PEERCLOSEWAIT1;
203 } else {
204
205 goto again;
206 }
207 break;
208 case SMC_APPFINCLOSEWAIT:
209
210 if (txflags->peer_done_writing &&
211 !smc_close_sent_any_close(conn)) {
212
213 rc = smc_close_final(conn);
214 if (rc)
215 break;
216 }
217 sk->sk_state = SMC_CLOSED;
218 break;
219 case SMC_APPCLOSEWAIT1:
220 case SMC_APPCLOSEWAIT2:
221 if (!smc_cdc_rxed_any_close(conn))
222 smc_close_stream_wait(smc, timeout);
223 release_sock(sk);
224 cancel_delayed_work_sync(&conn->tx_work);
225 lock_sock(sk);
226 if (sk->sk_state != SMC_APPCLOSEWAIT1 &&
227 sk->sk_state != SMC_APPCLOSEWAIT2)
228 goto again;
229
230 rc = smc_close_final(conn);
231 if (rc)
232 break;
233 if (smc_cdc_rxed_any_close(conn)) {
234
235 sk->sk_state = SMC_CLOSED;
236 sock_put(sk);
237 } else {
238
239 sk->sk_state = SMC_PEERFINCLOSEWAIT;
240 }
241 break;
242 case SMC_PEERCLOSEWAIT1:
243 case SMC_PEERCLOSEWAIT2:
244 if (txflags->peer_done_writing &&
245 !smc_close_sent_any_close(conn)) {
246
247 rc = smc_close_final(conn);
248 if (rc)
249 break;
250 }
251
252 break;
253 case SMC_PEERFINCLOSEWAIT:
254
255 break;
256 case SMC_PROCESSABORT:
257 smc_close_abort(conn);
258 sk->sk_state = SMC_CLOSED;
259 break;
260 case SMC_PEERABORTWAIT:
261 case SMC_CLOSED:
262
263 break;
264 }
265
266 if (old_state != sk->sk_state)
267 sk->sk_state_change(sk);
268 return rc;
269}
270
271static void smc_close_passive_abort_received(struct smc_sock *smc)
272{
273 struct smc_cdc_conn_state_flags *txflags =
274 &smc->conn.local_tx_ctrl.conn_state_flags;
275 struct sock *sk = &smc->sk;
276
277 switch (sk->sk_state) {
278 case SMC_INIT:
279 case SMC_ACTIVE:
280 case SMC_APPCLOSEWAIT1:
281 sk->sk_state = SMC_PROCESSABORT;
282 sock_put(sk);
283 break;
284 case SMC_APPFINCLOSEWAIT:
285 sk->sk_state = SMC_PROCESSABORT;
286 break;
287 case SMC_PEERCLOSEWAIT1:
288 case SMC_PEERCLOSEWAIT2:
289 if (txflags->peer_done_writing &&
290 !smc_close_sent_any_close(&smc->conn))
291
292 sk->sk_state = SMC_PROCESSABORT;
293 else
294 sk->sk_state = SMC_CLOSED;
295 sock_put(sk);
296 break;
297 case SMC_APPCLOSEWAIT2:
298 case SMC_PEERFINCLOSEWAIT:
299 sk->sk_state = SMC_CLOSED;
300 sock_put(sk);
301 break;
302 case SMC_PEERABORTWAIT:
303 sk->sk_state = SMC_CLOSED;
304 break;
305 case SMC_PROCESSABORT:
306
307 break;
308 }
309}
310
311
312
313
314
315static void smc_close_passive_work(struct work_struct *work)
316{
317 struct smc_connection *conn = container_of(work,
318 struct smc_connection,
319 close_work);
320 struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
321 struct smc_cdc_conn_state_flags *rxflags;
322 struct sock *sk = &smc->sk;
323 int old_state;
324
325 lock_sock(sk);
326 old_state = sk->sk_state;
327
328 if (!conn->alert_token_local) {
329
330 smc_close_active_abort(smc);
331 goto wakeup;
332 }
333
334 rxflags = &conn->local_rx_ctrl.conn_state_flags;
335 if (rxflags->peer_conn_abort) {
336
337 smc_close_passive_abort_received(smc);
338 release_sock(&smc->sk);
339 cancel_delayed_work_sync(&conn->tx_work);
340 lock_sock(&smc->sk);
341 goto wakeup;
342 }
343
344 switch (sk->sk_state) {
345 case SMC_INIT:
346 if (atomic_read(&conn->bytes_to_rcv) ||
347 (rxflags->peer_done_writing &&
348 !smc_cdc_rxed_any_close(conn))) {
349 sk->sk_state = SMC_APPCLOSEWAIT1;
350 } else {
351 sk->sk_state = SMC_CLOSED;
352 sock_put(sk);
353 }
354 break;
355 case SMC_ACTIVE:
356 sk->sk_state = SMC_APPCLOSEWAIT1;
357
358
359
360 break;
361 case SMC_PEERCLOSEWAIT1:
362 if (rxflags->peer_done_writing)
363 sk->sk_state = SMC_PEERCLOSEWAIT2;
364
365
366 case SMC_PEERCLOSEWAIT2:
367 if (!smc_cdc_rxed_any_close(conn))
368 break;
369 if (sock_flag(sk, SOCK_DEAD) &&
370 smc_close_sent_any_close(conn)) {
371
372 sk->sk_state = SMC_CLOSED;
373 } else {
374
375 sk->sk_state = SMC_APPFINCLOSEWAIT;
376 }
377 sock_put(sk);
378 break;
379 case SMC_PEERFINCLOSEWAIT:
380 if (smc_cdc_rxed_any_close(conn)) {
381 sk->sk_state = SMC_CLOSED;
382 sock_put(sk);
383 }
384 break;
385 case SMC_APPCLOSEWAIT1:
386 case SMC_APPCLOSEWAIT2:
387
388
389
390 break;
391 case SMC_APPFINCLOSEWAIT:
392 case SMC_PEERABORTWAIT:
393 case SMC_PROCESSABORT:
394 case SMC_CLOSED:
395
396 break;
397 }
398
399wakeup:
400 sk->sk_data_ready(sk);
401 sk->sk_write_space(sk);
402
403 if (old_state != sk->sk_state) {
404 sk->sk_state_change(sk);
405 if ((sk->sk_state == SMC_CLOSED) &&
406 (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket))
407 smc_conn_free(conn);
408 }
409 release_sock(sk);
410 sock_put(sk);
411}
412
413int smc_close_shutdown_write(struct smc_sock *smc)
414{
415 struct smc_connection *conn = &smc->conn;
416 struct sock *sk = &smc->sk;
417 int old_state;
418 long timeout;
419 int rc = 0;
420
421 timeout = current->flags & PF_EXITING ?
422 0 : sock_flag(sk, SOCK_LINGER) ?
423 sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
424
425 old_state = sk->sk_state;
426again:
427 switch (sk->sk_state) {
428 case SMC_ACTIVE:
429 smc_close_stream_wait(smc, timeout);
430 release_sock(sk);
431 cancel_delayed_work_sync(&conn->tx_work);
432 lock_sock(sk);
433 if (sk->sk_state != SMC_ACTIVE)
434 goto again;
435
436 rc = smc_close_wr(conn);
437 if (rc)
438 break;
439 sk->sk_state = SMC_PEERCLOSEWAIT1;
440 break;
441 case SMC_APPCLOSEWAIT1:
442
443 if (!smc_cdc_rxed_any_close(conn))
444 smc_close_stream_wait(smc, timeout);
445 release_sock(sk);
446 cancel_delayed_work_sync(&conn->tx_work);
447 lock_sock(sk);
448 if (sk->sk_state != SMC_APPCLOSEWAIT1)
449 goto again;
450
451 rc = smc_close_wr(conn);
452 if (rc)
453 break;
454 sk->sk_state = SMC_APPCLOSEWAIT2;
455 break;
456 case SMC_APPCLOSEWAIT2:
457 case SMC_PEERFINCLOSEWAIT:
458 case SMC_PEERCLOSEWAIT1:
459 case SMC_PEERCLOSEWAIT2:
460 case SMC_APPFINCLOSEWAIT:
461 case SMC_PROCESSABORT:
462 case SMC_PEERABORTWAIT:
463
464 break;
465 }
466
467 if (old_state != sk->sk_state)
468 sk->sk_state_change(sk);
469 return rc;
470}
471
472
473void smc_close_init(struct smc_sock *smc)
474{
475 INIT_WORK(&smc->conn.close_work, smc_close_passive_work);
476}
477