Commit d18963cf authored by Ursula Braun's avatar Ursula Braun Committed by Jakub Kicinski

net/smc: improve close of terminated socket

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: default avatarUrsula Braun <ubraun@linux.ibm.com>
Signed-off-by: default avatarKarsten Graul <kgraul@linux.ibm.com>
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
parent c3d9494e
...@@ -65,8 +65,8 @@ static void smc_close_stream_wait(struct smc_sock *smc, long timeout) ...@@ -65,8 +65,8 @@ static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
rc = sk_wait_event(sk, &timeout, rc = sk_wait_event(sk, &timeout,
!smc_tx_prepared_sends(&smc->conn) || !smc_tx_prepared_sends(&smc->conn) ||
(sk->sk_err == ECONNABORTED) || sk->sk_err == ECONNABORTED ||
(sk->sk_err == ECONNRESET), sk->sk_err == ECONNRESET,
&wait); &wait);
if (rc) if (rc)
break; break;
...@@ -113,9 +113,6 @@ static void smc_close_active_abort(struct smc_sock *smc) ...@@ -113,9 +113,6 @@ static void smc_close_active_abort(struct smc_sock *smc)
{ {
struct sock *sk = &smc->sk; 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) { if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
sk->sk_err = ECONNABORTED; sk->sk_err = ECONNABORTED;
if (smc->clcsock && smc->clcsock->sk) { if (smc->clcsock && smc->clcsock->sk) {
...@@ -129,35 +126,26 @@ static void smc_close_active_abort(struct smc_sock *smc) ...@@ -129,35 +126,26 @@ static void smc_close_active_abort(struct smc_sock *smc)
release_sock(sk); release_sock(sk);
cancel_delayed_work_sync(&smc->conn.tx_work); cancel_delayed_work_sync(&smc->conn.tx_work);
lock_sock(sk); lock_sock(sk);
sk->sk_state = SMC_CLOSED;
sock_put(sk); /* passive closing */ sock_put(sk); /* passive closing */
break; break;
case SMC_APPCLOSEWAIT1: case SMC_APPCLOSEWAIT1:
case SMC_APPCLOSEWAIT2: 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); release_sock(sk);
cancel_delayed_work_sync(&smc->conn.tx_work); cancel_delayed_work_sync(&smc->conn.tx_work);
lock_sock(sk); lock_sock(sk);
sk->sk_state = SMC_CLOSED;
break; break;
case SMC_PEERCLOSEWAIT1: case SMC_PEERCLOSEWAIT1:
case SMC_PEERCLOSEWAIT2: case SMC_PEERCLOSEWAIT2:
if (!txflags->peer_conn_closed) { case SMC_PEERFINCLOSEWAIT:
/* just SHUTDOWN_SEND done */
sk->sk_state = SMC_PEERABORTWAIT;
} else {
sk->sk_state = SMC_CLOSED; sk->sk_state = SMC_CLOSED;
}
sock_put(sk); /* passive closing */ sock_put(sk); /* passive closing */
break; break;
case SMC_PROCESSABORT: case SMC_PROCESSABORT:
case SMC_APPFINCLOSEWAIT: case SMC_APPFINCLOSEWAIT:
sk->sk_state = SMC_CLOSED; sk->sk_state = SMC_CLOSED;
break; break;
case SMC_PEERFINCLOSEWAIT:
sock_put(sk); /* passive closing */
break;
case SMC_INIT: case SMC_INIT:
case SMC_PEERABORTWAIT: case SMC_PEERABORTWAIT:
case SMC_CLOSED: case SMC_CLOSED:
...@@ -215,8 +203,6 @@ int smc_close_active(struct smc_sock *smc) ...@@ -215,8 +203,6 @@ int smc_close_active(struct smc_sock *smc)
if (sk->sk_state == SMC_ACTIVE) { if (sk->sk_state == SMC_ACTIVE) {
/* send close request */ /* send close request */
rc = smc_close_final(conn); rc = smc_close_final(conn);
if (rc)
break;
sk->sk_state = SMC_PEERCLOSEWAIT1; sk->sk_state = SMC_PEERCLOSEWAIT1;
} else { } else {
/* peer event has changed the state */ /* peer event has changed the state */
...@@ -229,8 +215,6 @@ int smc_close_active(struct smc_sock *smc) ...@@ -229,8 +215,6 @@ int smc_close_active(struct smc_sock *smc)
!smc_close_sent_any_close(conn)) { !smc_close_sent_any_close(conn)) {
/* just shutdown wr done, send close request */ /* just shutdown wr done, send close request */
rc = smc_close_final(conn); rc = smc_close_final(conn);
if (rc)
break;
} }
sk->sk_state = SMC_CLOSED; sk->sk_state = SMC_CLOSED;
break; break;
...@@ -246,8 +230,6 @@ int smc_close_active(struct smc_sock *smc) ...@@ -246,8 +230,6 @@ int smc_close_active(struct smc_sock *smc)
goto again; goto again;
/* confirm close from peer */ /* confirm close from peer */
rc = smc_close_final(conn); rc = smc_close_final(conn);
if (rc)
break;
if (smc_cdc_rxed_any_close(conn)) { if (smc_cdc_rxed_any_close(conn)) {
/* peer has closed the socket already */ /* peer has closed the socket already */
sk->sk_state = SMC_CLOSED; sk->sk_state = SMC_CLOSED;
...@@ -263,8 +245,6 @@ int smc_close_active(struct smc_sock *smc) ...@@ -263,8 +245,6 @@ int smc_close_active(struct smc_sock *smc)
!smc_close_sent_any_close(conn)) { !smc_close_sent_any_close(conn)) {
/* just shutdown wr done, send close request */ /* just shutdown wr done, send close request */
rc = smc_close_final(conn); rc = smc_close_final(conn);
if (rc)
break;
} }
/* peer sending PeerConnectionClosed will cause transition */ /* peer sending PeerConnectionClosed will cause transition */
break; break;
...@@ -272,10 +252,12 @@ int smc_close_active(struct smc_sock *smc) ...@@ -272,10 +252,12 @@ int smc_close_active(struct smc_sock *smc)
/* peer sending PeerConnectionClosed will cause transition */ /* peer sending PeerConnectionClosed will cause transition */
break; break;
case SMC_PROCESSABORT: case SMC_PROCESSABORT:
smc_close_abort(conn); rc = smc_close_abort(conn);
sk->sk_state = SMC_CLOSED; sk->sk_state = SMC_CLOSED;
break; break;
case SMC_PEERABORTWAIT: case SMC_PEERABORTWAIT:
sk->sk_state = SMC_CLOSED;
break;
case SMC_CLOSED: case SMC_CLOSED:
/* nothing to do, add tracing in future patch */ /* nothing to do, add tracing in future patch */
break; break;
...@@ -451,8 +433,6 @@ int smc_close_shutdown_write(struct smc_sock *smc) ...@@ -451,8 +433,6 @@ int smc_close_shutdown_write(struct smc_sock *smc)
goto again; goto again;
/* send close wr request */ /* send close wr request */
rc = smc_close_wr(conn); rc = smc_close_wr(conn);
if (rc)
break;
sk->sk_state = SMC_PEERCLOSEWAIT1; sk->sk_state = SMC_PEERCLOSEWAIT1;
break; break;
case SMC_APPCLOSEWAIT1: case SMC_APPCLOSEWAIT1:
...@@ -466,8 +446,6 @@ int smc_close_shutdown_write(struct smc_sock *smc) ...@@ -466,8 +446,6 @@ int smc_close_shutdown_write(struct smc_sock *smc)
goto again; goto again;
/* confirm close from peer */ /* confirm close from peer */
rc = smc_close_wr(conn); rc = smc_close_wr(conn);
if (rc)
break;
sk->sk_state = SMC_APPCLOSEWAIT2; sk->sk_state = SMC_APPCLOSEWAIT2;
break; break;
case SMC_APPCLOSEWAIT2: case SMC_APPCLOSEWAIT2:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment