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

net/smc: cancel send and receive for terminated socket



The resources for a terminated socket are being cleaned up.
This patch makes sure
* no more data is received for an actively terminated socket
* no more data is sent for an actively or passively terminated socket

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 fe28afe2
Loading
Loading
Loading
Loading
+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;
+5 −2
Original line number Diff line number Diff line
@@ -66,7 +66,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,6 +96,8 @@ 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);
}
@@ -326,7 +329,7 @@ static void smc_close_passive_work(struct work_struct *work)
	lock_sock(sk);
	old_state = sk->sk_state;

	if (!conn->alert_token_local) {
	if (conn->killed) {
		/* abnormal termination */
		smc_close_active_abort(smc);
		goto wakeup;
+1 −0
Original line number Diff line number Diff line
@@ -500,6 +500,7 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr)
		conn = rb_entry(node, struct smc_connection, alert_node);
		smc = container_of(conn, struct smc_sock, conn);
		sock_hold(&smc->sk); /* sock_put in close work */
		conn->killed = 1;
		conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
		__smc_lgr_unregister_conn(conn);
		conn->lgr = NULL;
+8 −2
Original line number Diff line number Diff line
@@ -201,6 +201,8 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo,
{
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
	struct smc_connection *conn = &smc->conn;
	struct smc_cdc_conn_state_flags *cflags =
					&conn->local_tx_ctrl.conn_state_flags;
	struct sock *sk = &smc->sk;
	int rc;

@@ -210,7 +212,9 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo,
	add_wait_queue(sk_sleep(sk), &wait);
	rc = sk_wait_event(sk, timeo,
			   sk->sk_err ||
			   cflags->peer_conn_abort ||
			   sk->sk_shutdown & RCV_SHUTDOWN ||
			   conn->killed ||
			   fcrit(conn),
			   &wait);
	remove_wait_queue(sk_sleep(sk), &wait);
@@ -314,11 +318,13 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg,
		if (read_done >= target || (pipe && read_done))
			break;

		if (conn->killed)
			break;

		if (smc_rx_recvmsg_data_available(smc))
			goto copy;

		if (sk->sk_shutdown & RCV_SHUTDOWN ||
		    conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) {
		if (sk->sk_shutdown & RCV_SHUTDOWN) {
			/* smc_cdc_msg_recv_action() could have run after
			 * above smc_rx_recvmsg_data_available()
			 */
Loading