Commit 82ad8621 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'smc-fixes'



Karsten Graul says:

====================
Fixes for -net, addressing two races in SMC receive path and
add a missing cleanup when the link group creating fails with
ISM devices and a VLAN id.
====================

Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
parents 2168da45 107529e3
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
	lgr = kzalloc(sizeof(*lgr), GFP_KERNEL);
	if (!lgr) {
		rc = SMC_CLC_DECL_MEM;
		goto out;
		goto ism_put_vlan;
	}
	lgr->is_smcd = ini->is_smcd;
	lgr->sync_err = 0;
@@ -289,6 +289,9 @@ clear_llc_lnk:
	smc_llc_link_clear(lnk);
free_lgr:
	kfree(lgr);
ism_put_vlan:
	if (ini->is_smcd && ini->vlan_id)
		smc_ism_put_vlan(ini->ism_dev, ini->vlan_id);
out:
	if (rc < 0) {
		if (rc == -ENOMEM)
+21 −8
Original line number Diff line number Diff line
@@ -211,8 +211,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo,
	rc = sk_wait_event(sk, timeo,
			   sk->sk_err ||
			   sk->sk_shutdown & RCV_SHUTDOWN ||
			   fcrit(conn) ||
			   smc_cdc_rxed_any_close_or_senddone(conn),
			   fcrit(conn),
			   &wait);
	remove_wait_queue(sk_sleep(sk), &wait);
	sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
@@ -262,6 +261,18 @@ static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len,
	return -EAGAIN;
}

static bool smc_rx_recvmsg_data_available(struct smc_sock *smc)
{
	struct smc_connection *conn = &smc->conn;

	if (smc_rx_data_available(conn))
		return true;
	else if (conn->urg_state == SMC_URG_VALID)
		/* we received a single urgent Byte - skip */
		smc_rx_update_cons(smc, 0);
	return false;
}

/* smc_rx_recvmsg - receive data from RMBE
 * @msg:	copy data to receive buffer
 * @pipe:	copy data to pipe if set - indicates splice() call
@@ -303,16 +314,18 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg,
		if (read_done >= target || (pipe && read_done))
			break;

		if (atomic_read(&conn->bytes_to_rcv))
		if (smc_rx_recvmsg_data_available(smc))
			goto copy;
		else if (conn->urg_state == SMC_URG_VALID)
			/* we received a single urgent Byte - skip */
			smc_rx_update_cons(smc, 0);

		if (sk->sk_shutdown & RCV_SHUTDOWN ||
		    smc_cdc_rxed_any_close_or_senddone(conn) ||
		    conn->local_tx_ctrl.conn_state_flags.peer_conn_abort)
		    conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) {
			/* smc_cdc_msg_recv_action() could have run after
			 * above smc_rx_recvmsg_data_available()
			 */
			if (smc_rx_recvmsg_data_available(smc))
				goto copy;
			break;
		}

		if (read_done) {
			if (sk->sk_err ||