linux/net/smc/smc_close.c
<<
>>
Prefs
   1/*
   2 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
   3 *
   4 *  Socket Closing - normal and abnormal
   5 *
   6 *  Copyright IBM Corp. 2016
   7 *
   8 *  Author(s):  Ursula Braun <ubraun@linux.vnet.ibm.com>
   9 */
  10
  11#include <linux/workqueue.h>
  12#include <linux/sched/signal.h>
  13
  14#include <net/sock.h>
  15
  16#include "smc.h"
  17#include "smc_tx.h"
  18#include "smc_cdc.h"
  19#include "smc_close.h"
  20
  21#define SMC_CLOSE_WAIT_TX_PENDS_TIME            (5 * HZ)
  22
  23static void smc_close_cleanup_listen(struct sock *parent)
  24{
  25        struct sock *sk;
  26
  27        /* Close non-accepted connections */
  28        while ((sk = smc_accept_dequeue(parent, NULL)))
  29                smc_close_non_accepted(sk);
  30}
  31
  32static 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
  52/* wait for sndbuf data being transmitted */
  53static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
  54{
  55        DEFINE_WAIT_FUNC(wait, woken_wake_function);
  56        struct sock *sk = &smc->sk;
  57
  58        if (!timeout)
  59                return;
  60
  61        if (!smc_tx_prepared_sends(&smc->conn))
  62                return;
  63
  64        smc->wait_close_tx_prepared = 1;
  65        add_wait_queue(sk_sleep(sk), &wait);
  66        while (!signal_pending(current) && timeout) {
  67                int rc;
  68
  69                rc = sk_wait_event(sk, &timeout,
  70                                   !smc_tx_prepared_sends(&smc->conn) ||
  71                                   (sk->sk_err == ECONNABORTED) ||
  72                                   (sk->sk_err == ECONNRESET),
  73                                   &wait);
  74                if (rc)
  75                        break;
  76        }
  77        remove_wait_queue(sk_sleep(sk), &wait);
  78        smc->wait_close_tx_prepared = 0;
  79}
  80
  81void smc_close_wake_tx_prepared(struct smc_sock *smc)
  82{
  83        if (smc->wait_close_tx_prepared)
  84                /* wake up socket closing */
  85                smc->sk.sk_state_change(&smc->sk);
  86}
  87
  88static int smc_close_wr(struct smc_connection *conn)
  89{
  90        conn->local_tx_ctrl.conn_state_flags.peer_done_writing = 1;
  91
  92        return smc_cdc_get_slot_and_msg_send(conn);
  93}
  94
  95static int smc_close_final(struct smc_connection *conn)
  96{
  97        if (atomic_read(&conn->bytes_to_rcv))
  98                conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
  99        else
 100                conn->local_tx_ctrl.conn_state_flags.peer_conn_closed = 1;
 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
 113 * RDMA communication no longer possible
 114 */
 115void smc_close_active_abort(struct smc_sock *smc)
 116{
 117        struct smc_cdc_conn_state_flags *txflags =
 118                &smc->conn.local_tx_ctrl.conn_state_flags;
 119
 120        smc->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        }
 125        switch (smc->sk.sk_state) {
 126        case SMC_INIT:
 127        case SMC_ACTIVE:
 128                smc->sk.sk_state = SMC_PEERABORTWAIT;
 129                break;
 130        case SMC_APPCLOSEWAIT1:
 131        case SMC_APPCLOSEWAIT2:
 132                txflags->peer_conn_abort = 1;
 133                sock_release(smc->clcsock);
 134                if (!smc_cdc_rxed_any_close(&smc->conn))
 135                        smc->sk.sk_state = SMC_PEERABORTWAIT;
 136                else
 137                        smc->sk.sk_state = SMC_CLOSED;
 138                break;
 139        case SMC_PEERCLOSEWAIT1:
 140        case SMC_PEERCLOSEWAIT2:
 141                if (!txflags->peer_conn_closed) {
 142                        smc->sk.sk_state = SMC_PEERABORTWAIT;
 143                        txflags->peer_conn_abort = 1;
 144                        sock_release(smc->clcsock);
 145                } else {
 146                        smc->sk.sk_state = SMC_CLOSED;
 147                }
 148                break;
 149        case SMC_PROCESSABORT:
 150        case SMC_APPFINCLOSEWAIT:
 151                if (!txflags->peer_conn_closed) {
 152                        txflags->peer_conn_abort = 1;
 153                        sock_release(smc->clcsock);
 154                }
 155                smc->sk.sk_state = SMC_CLOSED;
 156                break;
 157        case SMC_PEERFINCLOSEWAIT:
 158        case SMC_PEERABORTWAIT:
 159        case SMC_CLOSED:
 160                break;
 161        }
 162
 163        sock_set_flag(&smc->sk, SOCK_DEAD);
 164        smc->sk.sk_state_change(&smc->sk);
 165}
 166
 167static inline bool smc_close_sent_any_close(struct smc_connection *conn)
 168{
 169        return conn->local_tx_ctrl.conn_state_flags.peer_conn_abort ||
 170               conn->local_tx_ctrl.conn_state_flags.peer_conn_closed;
 171}
 172
 173int smc_close_active(struct smc_sock *smc)
 174{
 175        struct smc_cdc_conn_state_flags *txflags =
 176                &smc->conn.local_tx_ctrl.conn_state_flags;
 177        long timeout = SMC_MAX_STREAM_WAIT_TIMEOUT;
 178        struct smc_connection *conn = &smc->conn;
 179        struct sock *sk = &smc->sk;
 180        int old_state;
 181        int rc = 0;
 182
 183        if (sock_flag(sk, SOCK_LINGER) &&
 184            !(current->flags & PF_EXITING))
 185                timeout = sk->sk_lingertime;
 186
 187again:
 188        old_state = sk->sk_state;
 189        switch (old_state) {
 190        case SMC_INIT:
 191                sk->sk_state = SMC_CLOSED;
 192                if (smc->smc_listen_work.func)
 193                        cancel_work_sync(&smc->smc_listen_work);
 194                break;
 195        case SMC_LISTEN:
 196                sk->sk_state = SMC_CLOSED;
 197                sk->sk_state_change(sk); /* wake up accept */
 198                if (smc->clcsock && smc->clcsock->sk) {
 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);
 202                }
 203                release_sock(sk);
 204                smc_close_cleanup_listen(sk);
 205                cancel_work_sync(&smc->smc_listen_work);
 206                lock_sock(sk);
 207                break;
 208        case SMC_ACTIVE:
 209                smc_close_stream_wait(smc, timeout);
 210                release_sock(sk);
 211                cancel_work_sync(&conn->tx_work);
 212                lock_sock(sk);
 213                if (sk->sk_state == SMC_ACTIVE) {
 214                        /* send close request */
 215                        rc = smc_close_final(conn);
 216                        sk->sk_state = SMC_PEERCLOSEWAIT1;
 217                } else {
 218                        /* peer event has changed the state */
 219                        goto again;
 220                }
 221                break;
 222        case SMC_APPFINCLOSEWAIT:
 223                /* socket already shutdown wr or both (active close) */
 224                if (txflags->peer_done_writing &&
 225                    !smc_close_sent_any_close(conn)) {
 226                        /* just shutdown wr done, send close request */
 227                        rc = smc_close_final(conn);
 228                }
 229                sk->sk_state = SMC_CLOSED;
 230                smc_close_wait_tx_pends(smc);
 231                break;
 232        case SMC_APPCLOSEWAIT1:
 233        case SMC_APPCLOSEWAIT2:
 234                if (!smc_cdc_rxed_any_close(conn))
 235                        smc_close_stream_wait(smc, timeout);
 236                release_sock(sk);
 237                cancel_work_sync(&conn->tx_work);
 238                lock_sock(sk);
 239                if (sk->sk_err != ECONNABORTED) {
 240                        /* confirm close from peer */
 241                        rc = smc_close_final(conn);
 242                        if (rc)
 243                                break;
 244                }
 245                if (smc_cdc_rxed_any_close(conn))
 246                        /* peer has closed the socket already */
 247                        sk->sk_state = SMC_CLOSED;
 248                else
 249                        /* peer has just issued a shutdown write */
 250                        sk->sk_state = SMC_PEERFINCLOSEWAIT;
 251                smc_close_wait_tx_pends(smc);
 252                break;
 253        case SMC_PEERCLOSEWAIT1:
 254        case SMC_PEERCLOSEWAIT2:
 255                if (txflags->peer_done_writing &&
 256                    !smc_close_sent_any_close(conn)) {
 257                        /* just shutdown wr done, send close request */
 258                        rc = smc_close_final(conn);
 259                }
 260                /* peer sending PeerConnectionClosed will cause transition */
 261                break;
 262        case SMC_PEERFINCLOSEWAIT:
 263                /* peer sending PeerConnectionClosed will cause transition */
 264                break;
 265        case SMC_PROCESSABORT:
 266                cancel_work_sync(&conn->tx_work);
 267                smc_close_abort(conn);
 268                sk->sk_state = SMC_CLOSED;
 269                smc_close_wait_tx_pends(smc);
 270                break;
 271        case SMC_PEERABORTWAIT:
 272        case SMC_CLOSED:
 273                /* nothing to do, add tracing in future patch */
 274                break;
 275        }
 276
 277        if (old_state != sk->sk_state)
 278                sk->sk_state_change(&smc->sk);
 279        return rc;
 280}
 281
 282static void smc_close_passive_abort_received(struct smc_sock *smc)
 283{
 284        struct smc_cdc_conn_state_flags *txflags =
 285                &smc->conn.local_tx_ctrl.conn_state_flags;
 286        struct sock *sk = &smc->sk;
 287
 288        switch (sk->sk_state) {
 289        case SMC_ACTIVE:
 290        case SMC_APPFINCLOSEWAIT:
 291        case SMC_APPCLOSEWAIT1:
 292        case SMC_APPCLOSEWAIT2:
 293                smc_close_abort(&smc->conn);
 294                sk->sk_state = SMC_PROCESSABORT;
 295                break;
 296        case SMC_PEERCLOSEWAIT1:
 297        case SMC_PEERCLOSEWAIT2:
 298                if (txflags->peer_done_writing &&
 299                    !smc_close_sent_any_close(&smc->conn)) {
 300                        /* just shutdown, but not yet closed locally */
 301                        smc_close_abort(&smc->conn);
 302                        sk->sk_state = SMC_PROCESSABORT;
 303                } else {
 304                        sk->sk_state = SMC_CLOSED;
 305                }
 306                break;
 307        case SMC_PEERFINCLOSEWAIT:
 308        case SMC_PEERABORTWAIT:
 309                sk->sk_state = SMC_CLOSED;
 310                break;
 311        case SMC_INIT:
 312        case SMC_PROCESSABORT:
 313        /* nothing to do, add tracing in future patch */
 314                break;
 315        }
 316}
 317
 318/* Some kind of closing has been received: peer_conn_closed, peer_conn_abort,
 319 * or peer_done_writing.
 320 */
 321static void smc_close_passive_work(struct work_struct *work)
 322{
 323        struct smc_connection *conn = container_of(work,
 324                                                   struct smc_connection,
 325                                                   close_work);
 326        struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
 327        struct smc_cdc_conn_state_flags *rxflags;
 328        struct sock *sk = &smc->sk;
 329        int old_state;
 330
 331        lock_sock(&smc->sk);
 332        old_state = sk->sk_state;
 333
 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;
 341        if (rxflags->peer_conn_abort) {
 342                smc_close_passive_abort_received(smc);
 343                goto wakeup;
 344        }
 345
 346        switch (sk->sk_state) {
 347        case SMC_INIT:
 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;
 354                break;
 355        case SMC_ACTIVE:
 356                sk->sk_state = SMC_APPCLOSEWAIT1;
 357                break;
 358        case SMC_PEERCLOSEWAIT1:
 359                if (rxflags->peer_done_writing)
 360                        sk->sk_state = SMC_PEERCLOSEWAIT2;
 361                /* fall through to check for closing */
 362        case SMC_PEERCLOSEWAIT2:
 363        case SMC_PEERFINCLOSEWAIT:
 364                if (!smc_cdc_rxed_any_close(&smc->conn))
 365                        break;
 366                if (sock_flag(sk, SOCK_DEAD) &&
 367                    smc_close_sent_any_close(conn)) {
 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                }
 374                break;
 375        case SMC_APPCLOSEWAIT1:
 376        case SMC_APPCLOSEWAIT2:
 377        case SMC_APPFINCLOSEWAIT:
 378        case SMC_PEERABORTWAIT:
 379        case SMC_PROCESSABORT:
 380        case SMC_CLOSED:
 381                /* nothing to do, add tracing in future patch */
 382                break;
 383        }
 384
 385wakeup:
 386        sk->sk_data_ready(sk); /* wakeup blocked rcvbuf consumers */
 387        sk->sk_write_space(sk); /* wakeup blocked sndbuf producers */
 388
 389        if (old_state != sk->sk_state) {
 390                sk->sk_state_change(sk);
 391                if ((sk->sk_state == SMC_CLOSED) &&
 392                    (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
 393                        smc_conn_free(&smc->conn);
 394                        schedule_delayed_work(&smc->sock_put_work,
 395                                              SMC_CLOSE_SOCK_PUT_DELAY);
 396                }
 397        }
 398        release_sock(&smc->sk);
 399}
 400
 401void 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);
 409}
 410
 411int smc_close_shutdown_write(struct smc_sock *smc)
 412{
 413        struct smc_connection *conn = &smc->conn;
 414        long timeout = SMC_MAX_STREAM_WAIT_TIMEOUT;
 415        struct sock *sk = &smc->sk;
 416        int old_state;
 417        int rc = 0;
 418
 419        if (sock_flag(sk, SOCK_LINGER))
 420                timeout = sk->sk_lingertime;
 421
 422again:
 423        old_state = sk->sk_state;
 424        switch (old_state) {
 425        case SMC_ACTIVE:
 426                smc_close_stream_wait(smc, timeout);
 427                release_sock(sk);
 428                cancel_work_sync(&conn->tx_work);
 429                lock_sock(sk);
 430                /* send close wr request */
 431                rc = smc_close_wr(conn);
 432                if (sk->sk_state == SMC_ACTIVE)
 433                        sk->sk_state = SMC_PEERCLOSEWAIT1;
 434                else
 435                        goto again;
 436                break;
 437        case SMC_APPCLOSEWAIT1:
 438                /* passive close */
 439                if (!smc_cdc_rxed_any_close(conn))
 440                        smc_close_stream_wait(smc, timeout);
 441                release_sock(sk);
 442                cancel_work_sync(&conn->tx_work);
 443                lock_sock(sk);
 444                /* confirm close from peer */
 445                rc = smc_close_wr(conn);
 446                sk->sk_state = SMC_APPCLOSEWAIT2;
 447                break;
 448        case SMC_APPCLOSEWAIT2:
 449        case SMC_PEERFINCLOSEWAIT:
 450        case SMC_PEERCLOSEWAIT1:
 451        case SMC_PEERCLOSEWAIT2:
 452        case SMC_APPFINCLOSEWAIT:
 453        case SMC_PROCESSABORT:
 454        case SMC_PEERABORTWAIT:
 455                /* nothing to do, add tracing in future patch */
 456                break;
 457        }
 458
 459        if (old_state != sk->sk_state)
 460                sk->sk_state_change(&smc->sk);
 461        return rc;
 462}
 463
 464/* Initialize close properties on connection establishment. */
 465void smc_close_init(struct smc_sock *smc)
 466{
 467        INIT_WORK(&smc->conn.close_work, smc_close_passive_work);
 468}
 469