linux/net/smc/smc_close.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
   4 *
   5 *  Socket Closing - normal and abnormal
   6 *
   7 *  Copyright IBM Corp. 2016
   8 *
   9 *  Author(s):  Ursula Braun <ubraun@linux.vnet.ibm.com>
  10 */
  11
  12#include <linux/workqueue.h>
  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        /* Close non-accepted connections */
  29        while ((sk = smc_accept_dequeue(parent, NULL)))
  30                smc_close_non_accepted(sk);
  31}
  32
  33/* wait for sndbuf data being transmitted */
  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                /* wake up socket closing */
  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/* terminate smc socket abnormally - active abort
  94 * link group is terminated, i.e. RDMA communication no longer possible
  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); /* passive closing */
 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                        /* just SHUTDOWN_SEND done */
 131                        sk->sk_state = SMC_PEERABORTWAIT;
 132                } else {
 133                        sk->sk_state = SMC_CLOSED;
 134                }
 135                sock_put(sk); /* passive closing */
 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); /* passive closing */
 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); /* wake up accept */
 182                if (smc->clcsock && smc->clcsock->sk) {
 183                        rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
 184                        /* wake up kernel_accept of smc_tcp_listen_worker */
 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                        /* send close request */
 199                        rc = smc_close_final(conn);
 200                        if (rc)
 201                                break;
 202                        sk->sk_state = SMC_PEERCLOSEWAIT1;
 203                } else {
 204                        /* peer event has changed the state */
 205                        goto again;
 206                }
 207                break;
 208        case SMC_APPFINCLOSEWAIT:
 209                /* socket already shutdown wr or both (active close) */
 210                if (txflags->peer_done_writing &&
 211                    !smc_close_sent_any_close(conn)) {
 212                        /* just shutdown wr done, send close request */
 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                /* confirm close from peer */
 230                rc = smc_close_final(conn);
 231                if (rc)
 232                        break;
 233                if (smc_cdc_rxed_any_close(conn)) {
 234                        /* peer has closed the socket already */
 235                        sk->sk_state = SMC_CLOSED;
 236                        sock_put(sk); /* postponed passive closing */
 237                } else {
 238                        /* peer has just issued a shutdown write */
 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                        /* just shutdown wr done, send close request */
 247                        rc = smc_close_final(conn);
 248                        if (rc)
 249                                break;
 250                }
 251                /* peer sending PeerConnectionClosed will cause transition */
 252                break;
 253        case SMC_PEERFINCLOSEWAIT:
 254                /* peer sending PeerConnectionClosed will cause transition */
 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                /* nothing to do, add tracing in future patch */
 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); /* passive closing */
 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                        /* just shutdown, but not yet closed locally */
 292                        sk->sk_state = SMC_PROCESSABORT;
 293                else
 294                        sk->sk_state = SMC_CLOSED;
 295                sock_put(sk); /* passive closing */
 296                break;
 297        case SMC_APPCLOSEWAIT2:
 298        case SMC_PEERFINCLOSEWAIT:
 299                sk->sk_state = SMC_CLOSED;
 300                sock_put(sk); /* passive closing */
 301                break;
 302        case SMC_PEERABORTWAIT:
 303                sk->sk_state = SMC_CLOSED;
 304                break;
 305        case SMC_PROCESSABORT:
 306        /* nothing to do, add tracing in future patch */
 307                break;
 308        }
 309}
 310
 311/* Either some kind of closing has been received: peer_conn_closed,
 312 * peer_conn_abort, or peer_done_writing
 313 * or the link group of the connection terminates abnormally.
 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                /* abnormal termination */
 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                /* peer has not received all data */
 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); /* passive closing */
 353                }
 354                break;
 355        case SMC_ACTIVE:
 356                sk->sk_state = SMC_APPCLOSEWAIT1;
 357                /* postpone sock_put() for passive closing to cover
 358                 * received SEND_SHUTDOWN as well
 359                 */
 360                break;
 361        case SMC_PEERCLOSEWAIT1:
 362                if (rxflags->peer_done_writing)
 363                        sk->sk_state = SMC_PEERCLOSEWAIT2;
 364                /* fall through */
 365                /* to check for closing */
 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                        /* smc_release has already been called locally */
 372                        sk->sk_state = SMC_CLOSED;
 373                } else {
 374                        /* just shutdown, but not yet closed locally */
 375                        sk->sk_state = SMC_APPFINCLOSEWAIT;
 376                }
 377                sock_put(sk); /* passive closing */
 378                break;
 379        case SMC_PEERFINCLOSEWAIT:
 380                if (smc_cdc_rxed_any_close(conn)) {
 381                        sk->sk_state = SMC_CLOSED;
 382                        sock_put(sk); /* passive closing */
 383                }
 384                break;
 385        case SMC_APPCLOSEWAIT1:
 386        case SMC_APPCLOSEWAIT2:
 387                /* postpone sock_put() for passive closing to cover
 388                 * received SEND_SHUTDOWN as well
 389                 */
 390                break;
 391        case SMC_APPFINCLOSEWAIT:
 392        case SMC_PEERABORTWAIT:
 393        case SMC_PROCESSABORT:
 394        case SMC_CLOSED:
 395                /* nothing to do, add tracing in future patch */
 396                break;
 397        }
 398
 399wakeup:
 400        sk->sk_data_ready(sk); /* wakeup blocked rcvbuf consumers */
 401        sk->sk_write_space(sk); /* wakeup blocked sndbuf producers */
 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); /* sock_hold done by schedulers of close_work */
 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                /* send close wr request */
 436                rc = smc_close_wr(conn);
 437                if (rc)
 438                        break;
 439                sk->sk_state = SMC_PEERCLOSEWAIT1;
 440                break;
 441        case SMC_APPCLOSEWAIT1:
 442                /* passive close */
 443                if (!smc_cdc_rxed_any_close(conn))
 444                        smc_close_stream_wait(smc, timeout);
 445                release_sock(sk);
 446                cancel_delayed_work_sync(&conn->tx_work);
 447                lock_sock(sk);
 448                if (sk->sk_state != SMC_APPCLOSEWAIT1)
 449                        goto again;
 450                /* confirm close from peer */
 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                /* nothing to do, add tracing in future patch */
 464                break;
 465        }
 466
 467        if (old_state != sk->sk_state)
 468                sk->sk_state_change(sk);
 469        return rc;
 470}
 471
 472/* Initialize close properties on connection establishment. */
 473void smc_close_init(struct smc_sock *smc)
 474{
 475        INIT_WORK(&smc->conn.close_work, smc_close_passive_work);
 476}
 477