Merge branch 'smc-fixes'
Karsten Graul says: ==================== net/smc: fixes 2020-09-03 Please apply the following patch series for smc to netdev's net tree. Patch 1 fixes the toleration of older SMC implementations. Patch 2 takes care of a problem that happens when SMCR is used after SMCD initialization failed. Patch 3 fixes a problem with freed send buffers, and patch 4 corrects refcounting when SMC terminates due to device removal. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b61ac5bb42
|
@ -116,7 +116,6 @@ static void smc_close_cancel_work(struct smc_sock *smc)
|
||||||
cancel_work_sync(&smc->conn.close_work);
|
cancel_work_sync(&smc->conn.close_work);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* terminate smc socket abnormally - active abort
|
/* terminate smc socket abnormally - active abort
|
||||||
|
@ -134,22 +133,22 @@ void smc_close_active_abort(struct smc_sock *smc)
|
||||||
}
|
}
|
||||||
switch (sk->sk_state) {
|
switch (sk->sk_state) {
|
||||||
case SMC_ACTIVE:
|
case SMC_ACTIVE:
|
||||||
sk->sk_state = SMC_PEERABORTWAIT;
|
|
||||||
smc_close_cancel_work(smc);
|
|
||||||
sk->sk_state = SMC_CLOSED;
|
|
||||||
sock_put(sk); /* passive closing */
|
|
||||||
break;
|
|
||||||
case SMC_APPCLOSEWAIT1:
|
case SMC_APPCLOSEWAIT1:
|
||||||
case SMC_APPCLOSEWAIT2:
|
case SMC_APPCLOSEWAIT2:
|
||||||
|
sk->sk_state = SMC_PEERABORTWAIT;
|
||||||
smc_close_cancel_work(smc);
|
smc_close_cancel_work(smc);
|
||||||
|
if (sk->sk_state != SMC_PEERABORTWAIT)
|
||||||
|
break;
|
||||||
sk->sk_state = SMC_CLOSED;
|
sk->sk_state = SMC_CLOSED;
|
||||||
sock_put(sk); /* postponed passive closing */
|
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_PEERABORTWAIT;
|
sk->sk_state = SMC_PEERABORTWAIT;
|
||||||
smc_close_cancel_work(smc);
|
smc_close_cancel_work(smc);
|
||||||
|
if (sk->sk_state != SMC_PEERABORTWAIT)
|
||||||
|
break;
|
||||||
sk->sk_state = SMC_CLOSED;
|
sk->sk_state = SMC_CLOSED;
|
||||||
smc_conn_free(&smc->conn);
|
smc_conn_free(&smc->conn);
|
||||||
release_clcsock = true;
|
release_clcsock = true;
|
||||||
|
@ -159,6 +158,8 @@ void smc_close_active_abort(struct smc_sock *smc)
|
||||||
case SMC_APPFINCLOSEWAIT:
|
case SMC_APPFINCLOSEWAIT:
|
||||||
sk->sk_state = SMC_PEERABORTWAIT;
|
sk->sk_state = SMC_PEERABORTWAIT;
|
||||||
smc_close_cancel_work(smc);
|
smc_close_cancel_work(smc);
|
||||||
|
if (sk->sk_state != SMC_PEERABORTWAIT)
|
||||||
|
break;
|
||||||
sk->sk_state = SMC_CLOSED;
|
sk->sk_state = SMC_CLOSED;
|
||||||
smc_conn_free(&smc->conn);
|
smc_conn_free(&smc->conn);
|
||||||
release_clcsock = true;
|
release_clcsock = true;
|
||||||
|
|
|
@ -1356,6 +1356,8 @@ create:
|
||||||
if (ini->is_smcd) {
|
if (ini->is_smcd) {
|
||||||
conn->rx_off = sizeof(struct smcd_cdc_msg);
|
conn->rx_off = sizeof(struct smcd_cdc_msg);
|
||||||
smcd_cdc_rx_init(conn); /* init tasklet for this conn */
|
smcd_cdc_rx_init(conn); /* init tasklet for this conn */
|
||||||
|
} else {
|
||||||
|
conn->rx_off = 0;
|
||||||
}
|
}
|
||||||
#ifndef KERNEL_HAS_ATOMIC64
|
#ifndef KERNEL_HAS_ATOMIC64
|
||||||
spin_lock_init(&conn->acurs_lock);
|
spin_lock_init(&conn->acurs_lock);
|
||||||
|
@ -1777,6 +1779,7 @@ int smc_buf_create(struct smc_sock *smc, bool is_smcd)
|
||||||
list_del(&smc->conn.sndbuf_desc->list);
|
list_del(&smc->conn.sndbuf_desc->list);
|
||||||
mutex_unlock(&smc->conn.lgr->sndbufs_lock);
|
mutex_unlock(&smc->conn.lgr->sndbufs_lock);
|
||||||
smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc);
|
smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc);
|
||||||
|
smc->conn.sndbuf_desc = NULL;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -841,6 +841,9 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)
|
||||||
struct smc_init_info ini;
|
struct smc_init_info ini;
|
||||||
int lnk_idx, rc = 0;
|
int lnk_idx, rc = 0;
|
||||||
|
|
||||||
|
if (!llc->qp_mtu)
|
||||||
|
goto out_reject;
|
||||||
|
|
||||||
ini.vlan_id = lgr->vlan_id;
|
ini.vlan_id = lgr->vlan_id;
|
||||||
smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);
|
smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);
|
||||||
if (!memcmp(llc->sender_gid, link->peer_gid, SMC_GID_SIZE) &&
|
if (!memcmp(llc->sender_gid, link->peer_gid, SMC_GID_SIZE) &&
|
||||||
|
@ -917,10 +920,20 @@ out:
|
||||||
kfree(qentry);
|
kfree(qentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool smc_llc_is_empty_llc_message(union smc_llc_msg *llc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(llc->raw.data); i++)
|
||||||
|
if (llc->raw.data[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool smc_llc_is_local_add_link(union smc_llc_msg *llc)
|
static bool smc_llc_is_local_add_link(union smc_llc_msg *llc)
|
||||||
{
|
{
|
||||||
if (llc->raw.hdr.common.type == SMC_LLC_ADD_LINK &&
|
if (llc->raw.hdr.common.type == SMC_LLC_ADD_LINK &&
|
||||||
!llc->add_link.qp_mtu && !llc->add_link.link_num)
|
smc_llc_is_empty_llc_message(llc))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue