diff options
Diffstat (limited to 'net/smc')
| -rw-r--r-- | net/smc/smc_close.c | 17 | ||||
| -rw-r--r-- | net/smc/smc_core.c | 3 | ||||
| -rw-r--r-- | net/smc/smc_llc.c | 15 | 
3 files changed, 26 insertions, 9 deletions
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index 290270c821ca..0e7409e469c0 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c @@ -116,7 +116,6 @@ static void smc_close_cancel_work(struct smc_sock *smc)  	cancel_work_sync(&smc->conn.close_work);  	cancel_delayed_work_sync(&smc->conn.tx_work);  	lock_sock(sk); -	sk->sk_state = SMC_CLOSED;  }  /* terminate smc socket abnormally - active abort @@ -134,22 +133,22 @@ void smc_close_active_abort(struct smc_sock *smc)  	}  	switch (sk->sk_state) {  	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_APPCLOSEWAIT2: +		sk->sk_state = SMC_PEERABORTWAIT;  		smc_close_cancel_work(smc); +		if (sk->sk_state != SMC_PEERABORTWAIT) +			break;  		sk->sk_state = SMC_CLOSED; -		sock_put(sk); /* postponed passive closing */ +		sock_put(sk); /* (postponed) passive closing */  		break;  	case SMC_PEERCLOSEWAIT1:  	case SMC_PEERCLOSEWAIT2:  	case SMC_PEERFINCLOSEWAIT:  		sk->sk_state = SMC_PEERABORTWAIT;  		smc_close_cancel_work(smc); +		if (sk->sk_state != SMC_PEERABORTWAIT) +			break;  		sk->sk_state = SMC_CLOSED;  		smc_conn_free(&smc->conn);  		release_clcsock = true; @@ -159,6 +158,8 @@ void smc_close_active_abort(struct smc_sock *smc)  	case SMC_APPFINCLOSEWAIT:  		sk->sk_state = SMC_PEERABORTWAIT;  		smc_close_cancel_work(smc); +		if (sk->sk_state != SMC_PEERABORTWAIT) +			break;  		sk->sk_state = SMC_CLOSED;  		smc_conn_free(&smc->conn);  		release_clcsock = true; @@ -372,7 +373,7 @@ static void smc_close_passive_work(struct work_struct *work)  	case SMC_PEERCLOSEWAIT1:  		if (rxflags->peer_done_writing)  			sk->sk_state = SMC_PEERCLOSEWAIT2; -		/* fall through */ +		fallthrough;  		/* to check for closing */  	case SMC_PEERCLOSEWAIT2:  		if (!smc_cdc_rxed_any_close(conn)) diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index b42fa3b00d00..a406627b1d55 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -1356,6 +1356,8 @@ create:  	if (ini->is_smcd) {  		conn->rx_off = sizeof(struct smcd_cdc_msg);  		smcd_cdc_rx_init(conn); /* init tasklet for this conn */ +	} else { +		conn->rx_off = 0;  	}  #ifndef KERNEL_HAS_ATOMIC64  	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);  		mutex_unlock(&smc->conn.lgr->sndbufs_lock);  		smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc); +		smc->conn.sndbuf_desc = NULL;  	}  	return rc;  } diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c index df5b0a6ea848..3ea33466ebe9 100644 --- a/net/smc/smc_llc.c +++ b/net/smc/smc_llc.c @@ -841,6 +841,9 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry)  	struct smc_init_info ini;  	int lnk_idx, rc = 0; +	if (!llc->qp_mtu) +		goto out_reject; +  	ini.vlan_id = lgr->vlan_id;  	smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);  	if (!memcmp(llc->sender_gid, link->peer_gid, SMC_GID_SIZE) && @@ -917,10 +920,20 @@ out:  	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)  {  	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 false;  }  | 
