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

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
...@@ -213,7 +213,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) ...@@ -213,7 +213,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
lgr = kzalloc(sizeof(*lgr), GFP_KERNEL); lgr = kzalloc(sizeof(*lgr), GFP_KERNEL);
if (!lgr) { if (!lgr) {
rc = SMC_CLC_DECL_MEM; rc = SMC_CLC_DECL_MEM;
goto out; goto ism_put_vlan;
} }
lgr->is_smcd = ini->is_smcd; lgr->is_smcd = ini->is_smcd;
lgr->sync_err = 0; lgr->sync_err = 0;
...@@ -289,6 +289,9 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) ...@@ -289,6 +289,9 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
smc_llc_link_clear(lnk); smc_llc_link_clear(lnk);
free_lgr: free_lgr:
kfree(lgr); kfree(lgr);
ism_put_vlan:
if (ini->is_smcd && ini->vlan_id)
smc_ism_put_vlan(ini->ism_dev, ini->vlan_id);
out: out:
if (rc < 0) { if (rc < 0) {
if (rc == -ENOMEM) if (rc == -ENOMEM)
......
...@@ -211,8 +211,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, ...@@ -211,8 +211,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo,
rc = sk_wait_event(sk, timeo, rc = sk_wait_event(sk, timeo,
sk->sk_err || sk->sk_err ||
sk->sk_shutdown & RCV_SHUTDOWN || sk->sk_shutdown & RCV_SHUTDOWN ||
fcrit(conn) || fcrit(conn),
smc_cdc_rxed_any_close_or_senddone(conn),
&wait); &wait);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); 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, ...@@ -262,6 +261,18 @@ static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len,
return -EAGAIN; 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 /* smc_rx_recvmsg - receive data from RMBE
* @msg: copy data to receive buffer * @msg: copy data to receive buffer
* @pipe: copy data to pipe if set - indicates splice() call * @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, ...@@ -303,16 +314,18 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg,
if (read_done >= target || (pipe && read_done)) if (read_done >= target || (pipe && read_done))
break; break;
if (atomic_read(&conn->bytes_to_rcv)) if (smc_rx_recvmsg_data_available(smc))
goto copy; 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 || 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; break;
}
if (read_done) { if (read_done) {
if (sk->sk_err || if (sk->sk_err ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment