net/smc: improve close of terminated socket
authorUrsula Braun <ubraun@linux.ibm.com>
Wed, 9 Oct 2019 08:07:47 +0000 (10:07 +0200)
committerJakub Kicinski <jakub.kicinski@netronome.com>
Thu, 10 Oct 2019 02:45:44 +0000 (19:45 -0700)
Make sure a terminated SMC socket reaches the CLOSED state.
Even if sending of close flags fails, change the socket state to
the intended state to avoid dangling sockets not reaching the
CLOSED state.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
net/smc/smc_close.c

index fc06720b53c1442a8dd3222ed7be482a8993ab92..1a858e59fc319a4a34de21ef81af7c23bfd604ca 100644 (file)
@@ -65,8 +65,8 @@ static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
 
                rc = sk_wait_event(sk, &timeout,
                                   !smc_tx_prepared_sends(&smc->conn) ||
-                                  (sk->sk_err == ECONNABORTED) ||
-                                  (sk->sk_err == ECONNRESET),
+                                  sk->sk_err == ECONNABORTED ||
+                                  sk->sk_err == ECONNRESET,
                                   &wait);
                if (rc)
                        break;
@@ -113,9 +113,6 @@ static void smc_close_active_abort(struct smc_sock *smc)
 {
        struct sock *sk = &smc->sk;
 
-       struct smc_cdc_conn_state_flags *txflags =
-               &smc->conn.local_tx_ctrl.conn_state_flags;
-
        if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
                sk->sk_err = ECONNABORTED;
                if (smc->clcsock && smc->clcsock->sk) {
@@ -129,35 +126,26 @@ static void smc_close_active_abort(struct smc_sock *smc)
                release_sock(sk);
                cancel_delayed_work_sync(&smc->conn.tx_work);
                lock_sock(sk);
+               sk->sk_state = SMC_CLOSED;
                sock_put(sk); /* passive closing */
                break;
        case SMC_APPCLOSEWAIT1:
        case SMC_APPCLOSEWAIT2:
-               if (!smc_cdc_rxed_any_close(&smc->conn))
-                       sk->sk_state = SMC_PEERABORTWAIT;
-               else
-                       sk->sk_state = SMC_CLOSED;
                release_sock(sk);
                cancel_delayed_work_sync(&smc->conn.tx_work);
                lock_sock(sk);
+               sk->sk_state = SMC_CLOSED;
                break;
        case SMC_PEERCLOSEWAIT1:
        case SMC_PEERCLOSEWAIT2:
-               if (!txflags->peer_conn_closed) {
-                       /* just SHUTDOWN_SEND done */
-                       sk->sk_state = SMC_PEERABORTWAIT;
-               } else {
-                       sk->sk_state = SMC_CLOSED;
-               }
+       case SMC_PEERFINCLOSEWAIT:
+               sk->sk_state = SMC_CLOSED;
                sock_put(sk); /* passive closing */
                break;
        case SMC_PROCESSABORT:
        case SMC_APPFINCLOSEWAIT:
                sk->sk_state = SMC_CLOSED;
                break;
-       case SMC_PEERFINCLOSEWAIT:
-               sock_put(sk); /* passive closing */
-               break;
        case SMC_INIT:
        case SMC_PEERABORTWAIT:
        case SMC_CLOSED:
@@ -215,8 +203,6 @@ again:
                if (sk->sk_state == SMC_ACTIVE) {
                        /* send close request */
                        rc = smc_close_final(conn);
-                       if (rc)
-                               break;
                        sk->sk_state = SMC_PEERCLOSEWAIT1;
                } else {
                        /* peer event has changed the state */
@@ -229,8 +215,6 @@ again:
                    !smc_close_sent_any_close(conn)) {
                        /* just shutdown wr done, send close request */
                        rc = smc_close_final(conn);
-                       if (rc)
-                               break;
                }
                sk->sk_state = SMC_CLOSED;
                break;
@@ -246,8 +230,6 @@ again:
                        goto again;
                /* confirm close from peer */
                rc = smc_close_final(conn);
-               if (rc)
-                       break;
                if (smc_cdc_rxed_any_close(conn)) {
                        /* peer has closed the socket already */
                        sk->sk_state = SMC_CLOSED;
@@ -263,8 +245,6 @@ again:
                    !smc_close_sent_any_close(conn)) {
                        /* just shutdown wr done, send close request */
                        rc = smc_close_final(conn);
-                       if (rc)
-                               break;
                }
                /* peer sending PeerConnectionClosed will cause transition */
                break;
@@ -272,10 +252,12 @@ again:
                /* peer sending PeerConnectionClosed will cause transition */
                break;
        case SMC_PROCESSABORT:
-               smc_close_abort(conn);
+               rc = smc_close_abort(conn);
                sk->sk_state = SMC_CLOSED;
                break;
        case SMC_PEERABORTWAIT:
+               sk->sk_state = SMC_CLOSED;
+               break;
        case SMC_CLOSED:
                /* nothing to do, add tracing in future patch */
                break;
@@ -451,8 +433,6 @@ again:
                        goto again;
                /* send close wr request */
                rc = smc_close_wr(conn);
-               if (rc)
-                       break;
                sk->sk_state = SMC_PEERCLOSEWAIT1;
                break;
        case SMC_APPCLOSEWAIT1:
@@ -466,8 +446,6 @@ again:
                        goto again;
                /* confirm close from peer */
                rc = smc_close_wr(conn);
-               if (rc)
-                       break;
                sk->sk_state = SMC_APPCLOSEWAIT2;
                break;
        case SMC_APPCLOSEWAIT2: