blob: babe05d385e71f02181f72683f4e0897448975a1 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Ursula Braunb38d7322017-01-09 16:55:25 +01002/*
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>
Ingo Molnarc3edc402017-02-02 08:35:14 +010013#include <linux/sched/signal.h>
14
Ursula Braunb38d7322017-01-09 16:55:25 +010015#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
Ursula Braunb38d7322017-01-09 16:55:25 +010022static void smc_close_cleanup_listen(struct sock *parent)
23{
24 struct sock *sk;
25
26 /* Close non-accepted connections */
27 while ((sk = smc_accept_dequeue(parent, NULL)))
28 smc_close_non_accepted(sk);
29}
30
Ursula Braunb38d7322017-01-09 16:55:25 +010031/* wait for sndbuf data being transmitted */
32static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
33{
34 DEFINE_WAIT_FUNC(wait, woken_wake_function);
35 struct sock *sk = &smc->sk;
36
37 if (!timeout)
38 return;
39
40 if (!smc_tx_prepared_sends(&smc->conn))
41 return;
42
43 smc->wait_close_tx_prepared = 1;
44 add_wait_queue(sk_sleep(sk), &wait);
45 while (!signal_pending(current) && timeout) {
46 int rc;
47
48 rc = sk_wait_event(sk, &timeout,
49 !smc_tx_prepared_sends(&smc->conn) ||
50 (sk->sk_err == ECONNABORTED) ||
51 (sk->sk_err == ECONNRESET),
52 &wait);
53 if (rc)
54 break;
55 }
56 remove_wait_queue(sk_sleep(sk), &wait);
57 smc->wait_close_tx_prepared = 0;
58}
59
60void smc_close_wake_tx_prepared(struct smc_sock *smc)
61{
62 if (smc->wait_close_tx_prepared)
63 /* wake up socket closing */
64 smc->sk.sk_state_change(&smc->sk);
65}
66
67static int smc_close_wr(struct smc_connection *conn)
68{
69 conn->local_tx_ctrl.conn_state_flags.peer_done_writing = 1;
70
71 return smc_cdc_get_slot_and_msg_send(conn);
72}
73
74static int smc_close_final(struct smc_connection *conn)
75{
76 if (atomic_read(&conn->bytes_to_rcv))
77 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
78 else
79 conn->local_tx_ctrl.conn_state_flags.peer_conn_closed = 1;
80
81 return smc_cdc_get_slot_and_msg_send(conn);
82}
83
84static int smc_close_abort(struct smc_connection *conn)
85{
86 conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
87
88 return smc_cdc_get_slot_and_msg_send(conn);
89}
90
91/* terminate smc socket abnormally - active abort
Ursula Braun732720f2018-01-25 11:15:35 +010092 * link group is terminated, i.e. RDMA communication no longer possible
Ursula Braunb38d7322017-01-09 16:55:25 +010093 */
Ursula Brauna8ae8902017-12-07 13:38:44 +010094static void smc_close_active_abort(struct smc_sock *smc)
Ursula Braunb38d7322017-01-09 16:55:25 +010095{
Ursula Braun3163c502018-01-24 10:28:12 +010096 struct sock *sk = &smc->sk;
97
Ursula Braunb38d7322017-01-09 16:55:25 +010098 struct smc_cdc_conn_state_flags *txflags =
99 &smc->conn.local_tx_ctrl.conn_state_flags;
100
Ursula Braun3163c502018-01-24 10:28:12 +0100101 sk->sk_err = ECONNABORTED;
Ursula Braunb38d7322017-01-09 16:55:25 +0100102 if (smc->clcsock && smc->clcsock->sk) {
103 smc->clcsock->sk->sk_err = ECONNABORTED;
104 smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
105 }
Ursula Braun3163c502018-01-24 10:28:12 +0100106 switch (sk->sk_state) {
Ursula Braunb38d7322017-01-09 16:55:25 +0100107 case SMC_INIT:
Ursula Braun46c28db2017-04-10 14:58:01 +0200108 case SMC_ACTIVE:
Ursula Braun3163c502018-01-24 10:28:12 +0100109 sk->sk_state = SMC_PEERABORTWAIT;
Ursula Braun611b63a2018-01-25 11:15:31 +0100110 release_sock(sk);
111 cancel_delayed_work_sync(&smc->conn.tx_work);
112 lock_sock(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100113 break;
114 case SMC_APPCLOSEWAIT1:
115 case SMC_APPCLOSEWAIT2:
Ursula Braunb38d7322017-01-09 16:55:25 +0100116 sock_release(smc->clcsock);
117 if (!smc_cdc_rxed_any_close(&smc->conn))
Ursula Braun3163c502018-01-24 10:28:12 +0100118 sk->sk_state = SMC_PEERABORTWAIT;
Ursula Braunb38d7322017-01-09 16:55:25 +0100119 else
Ursula Braun3163c502018-01-24 10:28:12 +0100120 sk->sk_state = SMC_CLOSED;
Ursula Braun611b63a2018-01-25 11:15:31 +0100121 release_sock(sk);
122 cancel_delayed_work_sync(&smc->conn.tx_work);
123 lock_sock(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100124 break;
125 case SMC_PEERCLOSEWAIT1:
126 case SMC_PEERCLOSEWAIT2:
127 if (!txflags->peer_conn_closed) {
Ursula Braun3163c502018-01-24 10:28:12 +0100128 sk->sk_state = SMC_PEERABORTWAIT;
Ursula Braunb38d7322017-01-09 16:55:25 +0100129 sock_release(smc->clcsock);
130 } else {
Ursula Braun3163c502018-01-24 10:28:12 +0100131 sk->sk_state = SMC_CLOSED;
Ursula Braunb38d7322017-01-09 16:55:25 +0100132 }
133 break;
134 case SMC_PROCESSABORT:
135 case SMC_APPFINCLOSEWAIT:
Ursula Braun732720f2018-01-25 11:15:35 +0100136 if (!txflags->peer_conn_closed)
Ursula Braunb38d7322017-01-09 16:55:25 +0100137 sock_release(smc->clcsock);
Ursula Braun3163c502018-01-24 10:28:12 +0100138 sk->sk_state = SMC_CLOSED;
Ursula Braunb38d7322017-01-09 16:55:25 +0100139 break;
140 case SMC_PEERFINCLOSEWAIT:
141 case SMC_PEERABORTWAIT:
142 case SMC_CLOSED:
143 break;
144 }
145
Ursula Braun3163c502018-01-24 10:28:12 +0100146 sock_set_flag(sk, SOCK_DEAD);
147 sk->sk_state_change(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100148}
149
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200150static inline bool smc_close_sent_any_close(struct smc_connection *conn)
151{
152 return conn->local_tx_ctrl.conn_state_flags.peer_conn_abort ||
153 conn->local_tx_ctrl.conn_state_flags.peer_conn_closed;
154}
155
Ursula Braunb38d7322017-01-09 16:55:25 +0100156int smc_close_active(struct smc_sock *smc)
157{
158 struct smc_cdc_conn_state_flags *txflags =
159 &smc->conn.local_tx_ctrl.conn_state_flags;
Ursula Braunb38d7322017-01-09 16:55:25 +0100160 struct smc_connection *conn = &smc->conn;
161 struct sock *sk = &smc->sk;
162 int old_state;
Ursula Braun8c96fee2017-09-21 09:16:34 +0200163 long timeout;
Ursula Braunb38d7322017-01-09 16:55:25 +0100164 int rc = 0;
165
Ursula Braun8c96fee2017-09-21 09:16:34 +0200166 timeout = current->flags & PF_EXITING ?
167 0 : sock_flag(sk, SOCK_LINGER) ?
168 sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
Ursula Braunb38d7322017-01-09 16:55:25 +0100169
Ursula Braunb38d7322017-01-09 16:55:25 +0100170 old_state = sk->sk_state;
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100171again:
172 switch (sk->sk_state) {
Ursula Braunb38d7322017-01-09 16:55:25 +0100173 case SMC_INIT:
174 sk->sk_state = SMC_CLOSED;
175 if (smc->smc_listen_work.func)
Ursula Braun46c28db2017-04-10 14:58:01 +0200176 cancel_work_sync(&smc->smc_listen_work);
Ursula Braunb38d7322017-01-09 16:55:25 +0100177 break;
178 case SMC_LISTEN:
179 sk->sk_state = SMC_CLOSED;
180 sk->sk_state_change(sk); /* wake up accept */
181 if (smc->clcsock && smc->clcsock->sk) {
182 rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
183 /* wake up kernel_accept of smc_tcp_listen_worker */
184 smc->clcsock->sk->sk_data_ready(smc->clcsock->sk);
185 }
186 release_sock(sk);
187 smc_close_cleanup_listen(sk);
Ursula Braun46c28db2017-04-10 14:58:01 +0200188 cancel_work_sync(&smc->smc_listen_work);
Ursula Braunb38d7322017-01-09 16:55:25 +0100189 lock_sock(sk);
190 break;
191 case SMC_ACTIVE:
192 smc_close_stream_wait(smc, timeout);
193 release_sock(sk);
Ursula Braun18e537c2017-09-21 09:16:33 +0200194 cancel_delayed_work_sync(&conn->tx_work);
Ursula Braunb38d7322017-01-09 16:55:25 +0100195 lock_sock(sk);
196 if (sk->sk_state == SMC_ACTIVE) {
197 /* send close request */
198 rc = smc_close_final(conn);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100199 if (rc)
200 break;
Ursula Braunb38d7322017-01-09 16:55:25 +0100201 sk->sk_state = SMC_PEERCLOSEWAIT1;
202 } else {
203 /* peer event has changed the state */
204 goto again;
205 }
206 break;
207 case SMC_APPFINCLOSEWAIT:
208 /* socket already shutdown wr or both (active close) */
209 if (txflags->peer_done_writing &&
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200210 !smc_close_sent_any_close(conn)) {
Ursula Braunb38d7322017-01-09 16:55:25 +0100211 /* just shutdown wr done, send close request */
212 rc = smc_close_final(conn);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100213 if (rc)
214 break;
Ursula Braunb38d7322017-01-09 16:55:25 +0100215 }
216 sk->sk_state = SMC_CLOSED;
Ursula Braunb38d7322017-01-09 16:55:25 +0100217 break;
218 case SMC_APPCLOSEWAIT1:
219 case SMC_APPCLOSEWAIT2:
220 if (!smc_cdc_rxed_any_close(conn))
221 smc_close_stream_wait(smc, timeout);
222 release_sock(sk);
Ursula Braun18e537c2017-09-21 09:16:33 +0200223 cancel_delayed_work_sync(&conn->tx_work);
Ursula Braunb38d7322017-01-09 16:55:25 +0100224 lock_sock(sk);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100225 if (sk->sk_state != SMC_APPCLOSEWAIT1 &&
226 sk->sk_state != SMC_APPCLOSEWAIT2)
227 goto again;
228 /* confirm close from peer */
229 rc = smc_close_final(conn);
230 if (rc)
231 break;
Ursula Braunb38d7322017-01-09 16:55:25 +0100232 if (smc_cdc_rxed_any_close(conn))
233 /* peer has closed the socket already */
234 sk->sk_state = SMC_CLOSED;
235 else
236 /* peer has just issued a shutdown write */
237 sk->sk_state = SMC_PEERFINCLOSEWAIT;
Ursula Braunb38d7322017-01-09 16:55:25 +0100238 break;
239 case SMC_PEERCLOSEWAIT1:
240 case SMC_PEERCLOSEWAIT2:
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200241 if (txflags->peer_done_writing &&
242 !smc_close_sent_any_close(conn)) {
243 /* just shutdown wr done, send close request */
244 rc = smc_close_final(conn);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100245 if (rc)
246 break;
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200247 }
248 /* peer sending PeerConnectionClosed will cause transition */
249 break;
Ursula Braunb38d7322017-01-09 16:55:25 +0100250 case SMC_PEERFINCLOSEWAIT:
251 /* peer sending PeerConnectionClosed will cause transition */
252 break;
253 case SMC_PROCESSABORT:
Ursula Braunb38d7322017-01-09 16:55:25 +0100254 smc_close_abort(conn);
255 sk->sk_state = SMC_CLOSED;
Ursula Braunb38d7322017-01-09 16:55:25 +0100256 break;
257 case SMC_PEERABORTWAIT:
258 case SMC_CLOSED:
259 /* nothing to do, add tracing in future patch */
260 break;
261 }
262
263 if (old_state != sk->sk_state)
Ursula Braun3163c502018-01-24 10:28:12 +0100264 sk->sk_state_change(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100265 return rc;
266}
267
268static void smc_close_passive_abort_received(struct smc_sock *smc)
269{
270 struct smc_cdc_conn_state_flags *txflags =
271 &smc->conn.local_tx_ctrl.conn_state_flags;
272 struct sock *sk = &smc->sk;
273
274 switch (sk->sk_state) {
275 case SMC_ACTIVE:
276 case SMC_APPFINCLOSEWAIT:
277 case SMC_APPCLOSEWAIT1:
278 case SMC_APPCLOSEWAIT2:
Ursula Braunb38d7322017-01-09 16:55:25 +0100279 sk->sk_state = SMC_PROCESSABORT;
280 break;
281 case SMC_PEERCLOSEWAIT1:
282 case SMC_PEERCLOSEWAIT2:
283 if (txflags->peer_done_writing &&
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200284 !smc_close_sent_any_close(&smc->conn)) {
Ursula Braunb38d7322017-01-09 16:55:25 +0100285 /* just shutdown, but not yet closed locally */
Ursula Braunb38d7322017-01-09 16:55:25 +0100286 sk->sk_state = SMC_PROCESSABORT;
287 } else {
288 sk->sk_state = SMC_CLOSED;
289 }
290 break;
291 case SMC_PEERFINCLOSEWAIT:
292 case SMC_PEERABORTWAIT:
293 sk->sk_state = SMC_CLOSED;
294 break;
295 case SMC_INIT:
296 case SMC_PROCESSABORT:
297 /* nothing to do, add tracing in future patch */
298 break;
299 }
300}
301
Ursula Braun732720f2018-01-25 11:15:35 +0100302/* Either some kind of closing has been received: peer_conn_closed,
303 * peer_conn_abort, or peer_done_writing
304 * or the link group of the connection terminates abnormally.
Ursula Braunb38d7322017-01-09 16:55:25 +0100305 */
Ursula Braun46c28db2017-04-10 14:58:01 +0200306static void smc_close_passive_work(struct work_struct *work)
Ursula Braunb38d7322017-01-09 16:55:25 +0100307{
Ursula Braun46c28db2017-04-10 14:58:01 +0200308 struct smc_connection *conn = container_of(work,
309 struct smc_connection,
310 close_work);
311 struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
312 struct smc_cdc_conn_state_flags *rxflags;
Ursula Braunb38d7322017-01-09 16:55:25 +0100313 struct sock *sk = &smc->sk;
314 int old_state;
315
Ursula Braun3163c502018-01-24 10:28:12 +0100316 lock_sock(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100317 old_state = sk->sk_state;
318
Ursula Braun46c28db2017-04-10 14:58:01 +0200319 if (!conn->alert_token_local) {
320 /* abnormal termination */
321 smc_close_active_abort(smc);
322 goto wakeup;
323 }
324
Ursula Braun3163c502018-01-24 10:28:12 +0100325 rxflags = &conn->local_rx_ctrl.conn_state_flags;
Ursula Braunb38d7322017-01-09 16:55:25 +0100326 if (rxflags->peer_conn_abort) {
Ursula Braun732720f2018-01-25 11:15:35 +0100327 /* peer has not received all data */
Ursula Braunb38d7322017-01-09 16:55:25 +0100328 smc_close_passive_abort_received(smc);
Ursula Braun611b63a2018-01-25 11:15:31 +0100329 release_sock(&smc->sk);
330 cancel_delayed_work_sync(&conn->tx_work);
331 lock_sock(&smc->sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100332 goto wakeup;
333 }
334
335 switch (sk->sk_state) {
336 case SMC_INIT:
Ursula Braun3163c502018-01-24 10:28:12 +0100337 if (atomic_read(&conn->bytes_to_rcv) ||
Ursula Braunb38d7322017-01-09 16:55:25 +0100338 (rxflags->peer_done_writing &&
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200339 !smc_cdc_rxed_any_close(conn)))
Ursula Braunb38d7322017-01-09 16:55:25 +0100340 sk->sk_state = SMC_APPCLOSEWAIT1;
341 else
342 sk->sk_state = SMC_CLOSED;
343 break;
344 case SMC_ACTIVE:
345 sk->sk_state = SMC_APPCLOSEWAIT1;
346 break;
347 case SMC_PEERCLOSEWAIT1:
348 if (rxflags->peer_done_writing)
349 sk->sk_state = SMC_PEERCLOSEWAIT2;
Gustavo A. R. Silva7f6b4372017-10-21 20:35:30 -0500350 /* fall through */
351 /* to check for closing */
Ursula Braunb38d7322017-01-09 16:55:25 +0100352 case SMC_PEERCLOSEWAIT2:
Ursula Braun3163c502018-01-24 10:28:12 +0100353 if (!smc_cdc_rxed_any_close(conn))
Ursula Braunb38d7322017-01-09 16:55:25 +0100354 break;
355 if (sock_flag(sk, SOCK_DEAD) &&
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200356 smc_close_sent_any_close(conn)) {
Ursula Braunb38d7322017-01-09 16:55:25 +0100357 /* smc_release has already been called locally */
358 sk->sk_state = SMC_CLOSED;
359 } else {
360 /* just shutdown, but not yet closed locally */
361 sk->sk_state = SMC_APPFINCLOSEWAIT;
362 }
363 break;
Ursula Braun5ac92a02018-01-25 11:15:32 +0100364 case SMC_PEERFINCLOSEWAIT:
365 if (smc_cdc_rxed_any_close(conn))
366 sk->sk_state = SMC_CLOSED;
367 break;
Ursula Braunb38d7322017-01-09 16:55:25 +0100368 case SMC_APPCLOSEWAIT1:
369 case SMC_APPCLOSEWAIT2:
370 case SMC_APPFINCLOSEWAIT:
371 case SMC_PEERABORTWAIT:
372 case SMC_PROCESSABORT:
373 case SMC_CLOSED:
374 /* nothing to do, add tracing in future patch */
375 break;
376 }
377
378wakeup:
Ursula Braunb38d7322017-01-09 16:55:25 +0100379 sk->sk_data_ready(sk); /* wakeup blocked rcvbuf consumers */
380 sk->sk_write_space(sk); /* wakeup blocked sndbuf producers */
381
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200382 if (old_state != sk->sk_state) {
383 sk->sk_state_change(sk);
384 if ((sk->sk_state == SMC_CLOSED) &&
385 (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
Ursula Braun3163c502018-01-24 10:28:12 +0100386 smc_conn_free(conn);
Ursula Brauna98bf8c02017-04-10 14:58:02 +0200387 schedule_delayed_work(&smc->sock_put_work,
388 SMC_CLOSE_SOCK_PUT_DELAY);
389 }
Ursula Braunb38d7322017-01-09 16:55:25 +0100390 }
Ursula Braun3163c502018-01-24 10:28:12 +0100391 release_sock(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100392}
393
394void smc_close_sock_put_work(struct work_struct *work)
395{
396 struct smc_sock *smc = container_of(to_delayed_work(work),
397 struct smc_sock,
398 sock_put_work);
399
Ursula Braunf16a7dd2017-01-09 16:55:26 +0100400 smc->sk.sk_prot->unhash(&smc->sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100401 sock_put(&smc->sk);
402}
403
404int smc_close_shutdown_write(struct smc_sock *smc)
405{
406 struct smc_connection *conn = &smc->conn;
Ursula Braunb38d7322017-01-09 16:55:25 +0100407 struct sock *sk = &smc->sk;
408 int old_state;
Ursula Braun8c96fee2017-09-21 09:16:34 +0200409 long timeout;
Ursula Braunb38d7322017-01-09 16:55:25 +0100410 int rc = 0;
411
Ursula Braun8c96fee2017-09-21 09:16:34 +0200412 timeout = current->flags & PF_EXITING ?
413 0 : sock_flag(sk, SOCK_LINGER) ?
414 sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
Ursula Braunb38d7322017-01-09 16:55:25 +0100415
Ursula Braunb38d7322017-01-09 16:55:25 +0100416 old_state = sk->sk_state;
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100417again:
418 switch (sk->sk_state) {
Ursula Braunb38d7322017-01-09 16:55:25 +0100419 case SMC_ACTIVE:
420 smc_close_stream_wait(smc, timeout);
421 release_sock(sk);
Ursula Braun18e537c2017-09-21 09:16:33 +0200422 cancel_delayed_work_sync(&conn->tx_work);
Ursula Braunb38d7322017-01-09 16:55:25 +0100423 lock_sock(sk);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100424 if (sk->sk_state != SMC_ACTIVE)
425 goto again;
Ursula Braunb38d7322017-01-09 16:55:25 +0100426 /* send close wr request */
427 rc = smc_close_wr(conn);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100428 if (rc)
429 break;
430 sk->sk_state = SMC_PEERCLOSEWAIT1;
Ursula Braunb38d7322017-01-09 16:55:25 +0100431 break;
432 case SMC_APPCLOSEWAIT1:
433 /* passive close */
434 if (!smc_cdc_rxed_any_close(conn))
435 smc_close_stream_wait(smc, timeout);
436 release_sock(sk);
Ursula Braun18e537c2017-09-21 09:16:33 +0200437 cancel_delayed_work_sync(&conn->tx_work);
Ursula Braunb38d7322017-01-09 16:55:25 +0100438 lock_sock(sk);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100439 if (sk->sk_state != SMC_APPCLOSEWAIT1)
440 goto again;
Ursula Braunb38d7322017-01-09 16:55:25 +0100441 /* confirm close from peer */
442 rc = smc_close_wr(conn);
Ursula Braunbbb96bf2018-01-24 10:28:16 +0100443 if (rc)
444 break;
Ursula Braunb38d7322017-01-09 16:55:25 +0100445 sk->sk_state = SMC_APPCLOSEWAIT2;
446 break;
447 case SMC_APPCLOSEWAIT2:
448 case SMC_PEERFINCLOSEWAIT:
449 case SMC_PEERCLOSEWAIT1:
450 case SMC_PEERCLOSEWAIT2:
451 case SMC_APPFINCLOSEWAIT:
452 case SMC_PROCESSABORT:
453 case SMC_PEERABORTWAIT:
454 /* nothing to do, add tracing in future patch */
455 break;
456 }
457
458 if (old_state != sk->sk_state)
Ursula Braun3163c502018-01-24 10:28:12 +0100459 sk->sk_state_change(sk);
Ursula Braunb38d7322017-01-09 16:55:25 +0100460 return rc;
461}
Ursula Braun46c28db2017-04-10 14:58:01 +0200462
463/* Initialize close properties on connection establishment. */
464void smc_close_init(struct smc_sock *smc)
465{
466 INIT_WORK(&smc->conn.close_work, smc_close_passive_work);
467}