Commit 81cf4f47 authored by Ursula Braun's avatar Ursula Braun Committed by Jakub Kicinski
Browse files

net/smc: remove close abort worker



With the introduction of the link group termination worker there is
no longer a need to postpone smc_close_active_abort() to a worker.
To protect socket destruction due to normal and abnormal socket
closing, the socket refcount is increased.

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 f528ba24
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -167,6 +167,7 @@ static int smc_release(struct socket *sock)
	if (!sk)
	if (!sk)
		goto out;
		goto out;


	sock_hold(sk); /* sock_put below */
	smc = smc_sk(sk);
	smc = smc_sk(sk);


	/* cleanup for a dangling non-blocking connect */
	/* cleanup for a dangling non-blocking connect */
@@ -189,6 +190,7 @@ static int smc_release(struct socket *sock)
	sock->sk = NULL;
	sock->sk = NULL;
	release_sock(sk);
	release_sock(sk);


	sock_put(sk); /* sock_hold above */
	sock_put(sk); /* final sock_put */
	sock_put(sk); /* final sock_put */
out:
out:
	return rc;
	return rc;
@@ -970,12 +972,14 @@ void smc_close_non_accepted(struct sock *sk)
{
{
	struct smc_sock *smc = smc_sk(sk);
	struct smc_sock *smc = smc_sk(sk);


	sock_hold(sk); /* sock_put below */
	lock_sock(sk);
	lock_sock(sk);
	if (!sk->sk_lingertime)
	if (!sk->sk_lingertime)
		/* wait for peer closing */
		/* wait for peer closing */
		sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
		sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
	__smc_release(smc);
	__smc_release(smc);
	release_sock(sk);
	release_sock(sk);
	sock_put(sk); /* sock_hold above */
	sock_put(sk); /* final sock_put */
	sock_put(sk); /* final sock_put */
}
}


+11 −7
Original line number Original line Diff line number Diff line
@@ -113,9 +113,10 @@ int smc_close_abort(struct smc_connection *conn)
/* terminate smc socket abnormally - active abort
/* terminate smc socket abnormally - active abort
 * link group is terminated, i.e. RDMA communication no longer possible
 * link group is terminated, i.e. RDMA communication no longer possible
 */
 */
static void smc_close_active_abort(struct smc_sock *smc)
void smc_close_active_abort(struct smc_sock *smc)
{
{
	struct sock *sk = &smc->sk;
	struct sock *sk = &smc->sk;
	bool release_clcsock = false;


	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;
@@ -137,11 +138,14 @@ static void smc_close_active_abort(struct smc_sock *smc)
		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;
		sk->sk_state = SMC_CLOSED;
		sock_put(sk); /* postponed passive closing */
		break;
		break;
	case SMC_PEERCLOSEWAIT1:
	case SMC_PEERCLOSEWAIT1:
	case SMC_PEERCLOSEWAIT2:
	case SMC_PEERCLOSEWAIT2:
	case SMC_PEERFINCLOSEWAIT:
	case SMC_PEERFINCLOSEWAIT:
		sk->sk_state = SMC_CLOSED;
		sk->sk_state = SMC_CLOSED;
		smc_conn_free(&smc->conn);
		release_clcsock = true;
		sock_put(sk); /* passive closing */
		sock_put(sk); /* passive closing */
		break;
		break;
	case SMC_PROCESSABORT:
	case SMC_PROCESSABORT:
@@ -156,6 +160,12 @@ static void smc_close_active_abort(struct smc_sock *smc)


	sock_set_flag(sk, SOCK_DEAD);
	sock_set_flag(sk, SOCK_DEAD);
	sk->sk_state_change(sk);
	sk->sk_state_change(sk);

	if (release_clcsock) {
		release_sock(sk);
		smc_clcsock_release(smc);
		lock_sock(sk);
	}
}
}


static inline bool smc_close_sent_any_close(struct smc_connection *conn)
static inline bool smc_close_sent_any_close(struct smc_connection *conn)
@@ -328,12 +338,6 @@ static void smc_close_passive_work(struct work_struct *work)
	lock_sock(sk);
	lock_sock(sk);
	old_state = sk->sk_state;
	old_state = sk->sk_state;


	if (conn->killed) {
		/* abnormal termination */
		smc_close_active_abort(smc);
		goto wakeup;
	}

	rxflags = &conn->local_rx_ctrl.conn_state_flags;
	rxflags = &conn->local_rx_ctrl.conn_state_flags;
	if (rxflags->peer_conn_abort) {
	if (rxflags->peer_conn_abort) {
		/* peer has not received all data */
		/* peer has not received all data */
+1 −0
Original line number Original line Diff line number Diff line
@@ -25,5 +25,6 @@ int smc_close_shutdown_write(struct smc_sock *smc);
void smc_close_init(struct smc_sock *smc);
void smc_close_init(struct smc_sock *smc);
void smc_clcsock_release(struct smc_sock *smc);
void smc_clcsock_release(struct smc_sock *smc);
int smc_close_abort(struct smc_connection *conn);
int smc_close_abort(struct smc_connection *conn);
void smc_close_active_abort(struct smc_sock *smc);


#endif /* SMC_CLOSE_H */
#endif /* SMC_CLOSE_H */
+3 −3
Original line number Original line Diff line number Diff line
@@ -519,9 +519,7 @@ static void smc_conn_kill(struct smc_connection *conn)
	smc_sk_wake_ups(smc);
	smc_sk_wake_ups(smc);
	smc_lgr_unregister_conn(conn);
	smc_lgr_unregister_conn(conn);
	smc->sk.sk_err = ECONNABORTED;
	smc->sk.sk_err = ECONNABORTED;
	sock_hold(&smc->sk); /* sock_put in close work */
	smc_close_active_abort(smc);
	if (!schedule_work(&conn->close_work))
		sock_put(&smc->sk);
}
}


/* terminate link group */
/* terminate link group */
@@ -544,9 +542,11 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr)
		read_unlock_bh(&lgr->conns_lock);
		read_unlock_bh(&lgr->conns_lock);
		conn = rb_entry(node, struct smc_connection, alert_node);
		conn = rb_entry(node, struct smc_connection, alert_node);
		smc = container_of(conn, struct smc_sock, conn);
		smc = container_of(conn, struct smc_sock, conn);
		sock_hold(&smc->sk); /* sock_put below */
		lock_sock(&smc->sk);
		lock_sock(&smc->sk);
		smc_conn_kill(conn);
		smc_conn_kill(conn);
		release_sock(&smc->sk);
		release_sock(&smc->sk);
		sock_put(&smc->sk); /* sock_hold above */
		read_lock_bh(&lgr->conns_lock);
		read_lock_bh(&lgr->conns_lock);
		node = rb_first(&lgr->conns_all);
		node = rb_first(&lgr->conns_all);
	}
	}