~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/smc/smc_close.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /net/smc/smc_close.c (Version linux-6.11.5) and /net/smc/smc_close.c (Version linux-4.12.14)


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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php