diff options
Diffstat (limited to 'net/smc/smc_close.c')
| -rw-r--r-- | net/smc/smc_close.c | 31 | 
1 files changed, 18 insertions, 13 deletions
| diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index 3c2e166b5d22..48615d2ac4aa 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   *  Shared Memory Communications over RDMA (SMC-R) and RoCE   * @@ -174,15 +175,15 @@ int smc_close_active(struct smc_sock *smc)  {  	struct smc_cdc_conn_state_flags *txflags =  		&smc->conn.local_tx_ctrl.conn_state_flags; -	long timeout = SMC_MAX_STREAM_WAIT_TIMEOUT;  	struct smc_connection *conn = &smc->conn;  	struct sock *sk = &smc->sk;  	int old_state; +	long timeout;  	int rc = 0; -	if (sock_flag(sk, SOCK_LINGER) && -	    !(current->flags & PF_EXITING)) -		timeout = sk->sk_lingertime; +	timeout = current->flags & PF_EXITING ? +		  0 : sock_flag(sk, SOCK_LINGER) ? +		      sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;  again:  	old_state = sk->sk_state; @@ -208,7 +209,7 @@ again:  	case SMC_ACTIVE:  		smc_close_stream_wait(smc, timeout);  		release_sock(sk); -		cancel_work_sync(&conn->tx_work); +		cancel_delayed_work_sync(&conn->tx_work);  		lock_sock(sk);  		if (sk->sk_state == SMC_ACTIVE) {  			/* send close request */ @@ -234,7 +235,7 @@ again:  		if (!smc_cdc_rxed_any_close(conn))  			smc_close_stream_wait(smc, timeout);  		release_sock(sk); -		cancel_work_sync(&conn->tx_work); +		cancel_delayed_work_sync(&conn->tx_work);  		lock_sock(sk);  		if (sk->sk_err != ECONNABORTED) {  			/* confirm close from peer */ @@ -263,7 +264,9 @@ again:  		/* peer sending PeerConnectionClosed will cause transition */  		break;  	case SMC_PROCESSABORT: -		cancel_work_sync(&conn->tx_work); +		release_sock(sk); +		cancel_delayed_work_sync(&conn->tx_work); +		lock_sock(sk);  		smc_close_abort(conn);  		sk->sk_state = SMC_CLOSED;  		smc_close_wait_tx_pends(smc); @@ -358,7 +361,8 @@ static void smc_close_passive_work(struct work_struct *work)  	case SMC_PEERCLOSEWAIT1:  		if (rxflags->peer_done_writing)  			sk->sk_state = SMC_PEERCLOSEWAIT2; -		/* fall through to check for closing */ +		/* fall through */ +		/* to check for closing */  	case SMC_PEERCLOSEWAIT2:  	case SMC_PEERFINCLOSEWAIT:  		if (!smc_cdc_rxed_any_close(&smc->conn)) @@ -411,13 +415,14 @@ void smc_close_sock_put_work(struct work_struct *work)  int smc_close_shutdown_write(struct smc_sock *smc)  {  	struct smc_connection *conn = &smc->conn; -	long timeout = SMC_MAX_STREAM_WAIT_TIMEOUT;  	struct sock *sk = &smc->sk;  	int old_state; +	long timeout;  	int rc = 0; -	if (sock_flag(sk, SOCK_LINGER)) -		timeout = sk->sk_lingertime; +	timeout = current->flags & PF_EXITING ? +		  0 : sock_flag(sk, SOCK_LINGER) ? +		      sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;  again:  	old_state = sk->sk_state; @@ -425,7 +430,7 @@ again:  	case SMC_ACTIVE:  		smc_close_stream_wait(smc, timeout);  		release_sock(sk); -		cancel_work_sync(&conn->tx_work); +		cancel_delayed_work_sync(&conn->tx_work);  		lock_sock(sk);  		/* send close wr request */  		rc = smc_close_wr(conn); @@ -439,7 +444,7 @@ again:  		if (!smc_cdc_rxed_any_close(conn))  			smc_close_stream_wait(smc, timeout);  		release_sock(sk); -		cancel_work_sync(&conn->tx_work); +		cancel_delayed_work_sync(&conn->tx_work);  		lock_sock(sk);  		/* confirm close from peer */  		rc = smc_close_wr(conn); | 
