Commit bd71a357 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-smc-improve-termination-handling'



Karsten Graul says:

====================
More patches to address abnormal termination processing of
sockets and link groups.
====================

Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
parents fe28afe2 81cf4f47
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ static int smc_release(struct socket *sock)
	if (!sk)
		goto out;

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

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

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

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

+1 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ struct smc_connection {
						 * 0 for SMC-R, 32 for SMC-D
						 */
	u64			peer_token;	/* SMC-D token of peer */
	u8			killed : 1;	/* abnormal termination */
};

struct smc_sock {				/* smc sock container */
+2 −2
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ int smc_cdc_get_free_slot(struct smc_connection *conn,
	rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf,
				     wr_rdma_buf,
				     (struct smc_wr_tx_pend_priv **)pend);
	if (!conn->alert_token_local)
	if (conn->killed)
		/* abnormal termination */
		rc = -EPIPE;
	return rc;
@@ -328,7 +328,7 @@ static void smcd_cdc_rx_tsklet(unsigned long data)
	struct smcd_cdc_msg cdc;
	struct smc_sock *smc;

	if (!conn)
	if (!conn || conn->killed)
		return;

	data_cdc = (struct smcd_cdc_msg *)conn->rmb_desc->cpu_addr;
+19 −13
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/sched/signal.h>

#include <net/sock.h>
#include <net/tcp.h>

#include "smc.h"
#include "smc_tx.h"
@@ -66,7 +67,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 == ECONNRESET ||
				   smc->conn.killed,
				   &wait);
		if (rc)
			break;
@@ -95,11 +97,13 @@ static int smc_close_final(struct smc_connection *conn)
		conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
	else
		conn->local_tx_ctrl.conn_state_flags.peer_conn_closed = 1;
	if (conn->killed)
		return -EPIPE;

	return smc_cdc_get_slot_and_msg_send(conn);
}

static int smc_close_abort(struct smc_connection *conn)
int smc_close_abort(struct smc_connection *conn)
{
	conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;

@@ -109,16 +113,15 @@ static int smc_close_abort(struct smc_connection *conn)
/* terminate smc socket abnormally - active abort
 * 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;
	bool release_clcsock = false;

	if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
		sk->sk_err = ECONNABORTED;
		if (smc->clcsock && smc->clcsock->sk) {
			smc->clcsock->sk->sk_err = ECONNABORTED;
			smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
		}
		if (smc->clcsock && smc->clcsock->sk)
			tcp_abort(smc->clcsock->sk, ECONNABORTED);
	}
	switch (sk->sk_state) {
	case SMC_ACTIVE:
@@ -135,11 +138,14 @@ static void smc_close_active_abort(struct smc_sock *smc)
		cancel_delayed_work_sync(&smc->conn.tx_work);
		lock_sock(sk);
		sk->sk_state = SMC_CLOSED;
		sock_put(sk); /* postponed passive closing */
		break;
	case SMC_PEERCLOSEWAIT1:
	case SMC_PEERCLOSEWAIT2:
	case SMC_PEERFINCLOSEWAIT:
		sk->sk_state = SMC_CLOSED;
		smc_conn_free(&smc->conn);
		release_clcsock = true;
		sock_put(sk); /* passive closing */
		break;
	case SMC_PROCESSABORT:
@@ -154,6 +160,12 @@ static void smc_close_active_abort(struct smc_sock *smc)

	sock_set_flag(sk, SOCK_DEAD);
	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)
@@ -326,12 +338,6 @@ static void smc_close_passive_work(struct work_struct *work)
	lock_sock(sk);
	old_state = sk->sk_state;

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

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

#endif /* SMC_CLOSE_H */
Loading