diff options
Diffstat (limited to 'net/smc')
| -rw-r--r-- | net/smc/af_smc.c | 8 | ||||
| -rw-r--r-- | net/smc/smc_clc.h | 4 | ||||
| -rw-r--r-- | net/smc/smc_core.c | 72 | ||||
| -rw-r--r-- | net/smc/smc_core.h | 2 | ||||
| -rw-r--r-- | net/smc/smc_loopback.h | 1 | ||||
| -rw-r--r-- | net/smc/smc_pnet.c | 3 | ||||
| -rw-r--r-- | net/smc/smc_stats.c | 6 | ||||
| -rw-r--r-- | net/smc/smc_stats.h | 28 | ||||
| -rw-r--r-- | net/smc/smc_sysctl.c | 11 | 
9 files changed, 101 insertions, 34 deletions
| diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 8e3093938cd2..0316217b7687 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1466,10 +1466,6 @@ connect_abort:  static int smc_connect_check_aclc(struct smc_init_info *ini,  				  struct smc_clc_msg_accept_confirm *aclc)  { -	if (aclc->hdr.typev1 != SMC_TYPE_R && -	    aclc->hdr.typev1 != SMC_TYPE_D) -		return SMC_CLC_DECL_MODEUNSUPP; -  	if (aclc->hdr.version >= SMC_V2) {  		if ((aclc->hdr.typev1 == SMC_TYPE_R &&  		     !smcr_indicated(ini->smc_type_v2)) || @@ -1523,10 +1519,6 @@ static int __smc_connect(struct smc_sock *smc)  		ini->smcd_version &= ~SMC_V1;  		ini->smcr_version = 0;  		ini->smc_type_v1 = SMC_TYPE_N; -		if (!ini->smcd_version) { -			rc = SMC_CLC_DECL_GETVLANERR; -			goto fallback; -		}  	}  	rc = smc_find_proposal_devices(smc, ini); diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h index 467effb50cd6..5625fda2960b 100644 --- a/net/smc/smc_clc.h +++ b/net/smc/smc_clc.h @@ -145,6 +145,8 @@ struct smc_clc_v2_extension {  	);  	u8 user_eids[][SMC_MAX_EID_LEN];  }; +static_assert(offsetof(struct smc_clc_v2_extension, user_eids) == sizeof(struct smc_clc_v2_extension_fixed), +	      "struct member likely outside of struct_group_tagged()");  struct smc_clc_msg_proposal_prefix {	/* prefix part of clc proposal message*/  	__be32 outgoing_subnet;	/* subnet mask */ @@ -169,6 +171,8 @@ struct smc_clc_smcd_v2_extension {  	);  	struct smc_clc_smcd_gid_chid gidchid[];  }; +static_assert(offsetof(struct smc_clc_smcd_v2_extension, gidchid) == sizeof(struct smc_clc_smcd_v2_extension_fixed), +	      "struct member likely outside of struct_group_tagged()");  struct smc_clc_msg_proposal {	/* clc proposal message sent by Linux */  	struct smc_clc_msg_hdr hdr; diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 3b95828d9976..4e694860ece4 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -221,6 +221,35 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn)  	write_unlock_bh(&lgr->conns_lock);  } +static void smc_lgr_buf_list_add(struct smc_link_group *lgr, +				 bool is_rmb, +				 struct list_head *buf_list, +				 struct smc_buf_desc *buf_desc) +{ +	list_add(&buf_desc->list, buf_list); +	if (is_rmb) { +		lgr->alloc_rmbs += buf_desc->len; +		lgr->alloc_rmbs += +			lgr->is_smcd ? sizeof(struct smcd_cdc_msg) : 0; +	} else { +		lgr->alloc_sndbufs += buf_desc->len; +	} +} + +static void smc_lgr_buf_list_del(struct smc_link_group *lgr, +				 bool is_rmb, +				 struct smc_buf_desc *buf_desc) +{ +	list_del(&buf_desc->list); +	if (is_rmb) { +		lgr->alloc_rmbs -= buf_desc->len; +		lgr->alloc_rmbs -= +			lgr->is_smcd ? sizeof(struct smcd_cdc_msg) : 0; +	} else { +		lgr->alloc_sndbufs -= buf_desc->len; +	} +} +  int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb)  {  	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb); @@ -363,6 +392,10 @@ static int smc_nl_fill_lgr(struct smc_link_group *lgr,  	smc_target[SMC_MAX_PNETID_LEN] = 0;  	if (nla_put_string(skb, SMC_NLA_LGR_R_PNETID, smc_target))  		goto errattr; +	if (nla_put_uint(skb, SMC_NLA_LGR_R_SNDBUF_ALLOC, lgr->alloc_sndbufs)) +		goto errattr; +	if (nla_put_uint(skb, SMC_NLA_LGR_R_RMB_ALLOC, lgr->alloc_rmbs)) +		goto errattr;  	if (lgr->smc_version > SMC_V1) {  		v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_R_V2_COMMON);  		if (!v2_attrs) @@ -541,6 +574,10 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,  		goto errattr;  	if (nla_put_u32(skb, SMC_NLA_LGR_D_CHID, smc_ism_get_chid(lgr->smcd)))  		goto errattr; +	if (nla_put_uint(skb, SMC_NLA_LGR_D_SNDBUF_ALLOC, lgr->alloc_sndbufs)) +		goto errattr; +	if (nla_put_uint(skb, SMC_NLA_LGR_D_DMB_ALLOC, lgr->alloc_rmbs)) +		goto errattr;  	memcpy(smc_pnet, lgr->smcd->pnetid, SMC_MAX_PNETID_LEN);  	smc_pnet[SMC_MAX_PNETID_LEN] = 0;  	if (nla_put_string(skb, SMC_NLA_LGR_D_PNETID, smc_pnet)) @@ -1138,7 +1175,7 @@ static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb,  		lock = is_rmb ? &lgr->rmbs_lock :  				&lgr->sndbufs_lock;  		down_write(lock); -		list_del(&buf_desc->list); +		smc_lgr_buf_list_del(lgr, is_rmb, buf_desc);  		up_write(lock);  		smc_buf_free(lgr, is_rmb, buf_desc); @@ -1166,22 +1203,30 @@ static void smcd_buf_detach(struct smc_connection *conn)  static void smc_buf_unuse(struct smc_connection *conn,  			  struct smc_link_group *lgr)  { +	struct smc_sock *smc = container_of(conn, struct smc_sock, conn); +	bool is_smcd = lgr->is_smcd; +	int bufsize; +  	if (conn->sndbuf_desc) { -		if (!lgr->is_smcd && conn->sndbuf_desc->is_vm) { +		bufsize = conn->sndbuf_desc->len; +		if (!is_smcd && conn->sndbuf_desc->is_vm) {  			smcr_buf_unuse(conn->sndbuf_desc, false, lgr);  		} else { -			memzero_explicit(conn->sndbuf_desc->cpu_addr, conn->sndbuf_desc->len); +			memzero_explicit(conn->sndbuf_desc->cpu_addr, bufsize);  			WRITE_ONCE(conn->sndbuf_desc->used, 0);  		} +		SMC_STAT_RMB_SIZE(smc, is_smcd, false, false, bufsize);  	}  	if (conn->rmb_desc) { -		if (!lgr->is_smcd) { +		bufsize = conn->rmb_desc->len; +		if (!is_smcd) {  			smcr_buf_unuse(conn->rmb_desc, true, lgr);  		} else { -			memzero_explicit(conn->rmb_desc->cpu_addr, -					 conn->rmb_desc->len + sizeof(struct smcd_cdc_msg)); +			bufsize += sizeof(struct smcd_cdc_msg); +			memzero_explicit(conn->rmb_desc->cpu_addr, bufsize);  			WRITE_ONCE(conn->rmb_desc->used, 0);  		} +		SMC_STAT_RMB_SIZE(smc, is_smcd, true, false, bufsize);  	}  } @@ -1377,7 +1422,7 @@ static void __smc_lgr_free_bufs(struct smc_link_group *lgr, bool is_rmb)  			buf_list = &lgr->sndbufs[i];  		list_for_each_entry_safe(buf_desc, bf_desc, buf_list,  					 list) { -			list_del(&buf_desc->list); +			smc_lgr_buf_list_del(lgr, is_rmb, buf_desc);  			smc_buf_free(lgr, is_rmb, buf_desc);  		}  	} @@ -2250,7 +2295,7 @@ int smcr_buf_reg_lgr(struct smc_link *lnk)  }  static struct smc_buf_desc *smcr_new_buf_create(struct smc_link_group *lgr, -						bool is_rmb, int bufsize) +						int bufsize)  {  	struct smc_buf_desc *buf_desc; @@ -2390,7 +2435,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)  		buf_desc = smc_buf_get_slot(bufsize_comp, lock, buf_list);  		if (buf_desc) {  			buf_desc->is_dma_need_sync = 0; -			SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, bufsize); +			SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, true, bufsize);  			SMC_STAT_BUF_REUSE(smc, is_smcd, is_rmb);  			break; /* found reusable slot */  		} @@ -2398,7 +2443,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)  		if (is_smcd)  			buf_desc = smcd_new_buf_create(lgr, is_rmb, bufsize);  		else -			buf_desc = smcr_new_buf_create(lgr, is_rmb, bufsize); +			buf_desc = smcr_new_buf_create(lgr, bufsize);  		if (PTR_ERR(buf_desc) == -ENOMEM)  			break; @@ -2411,10 +2456,10 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)  		}  		SMC_STAT_RMB_ALLOC(smc, is_smcd, is_rmb); -		SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, bufsize); +		SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, true, bufsize);  		buf_desc->used = 1;  		down_write(lock); -		list_add(&buf_desc->list, buf_list); +		smc_lgr_buf_list_add(lgr, is_rmb, buf_list, buf_desc);  		up_write(lock);  		break; /* found */  	} @@ -2496,7 +2541,8 @@ create_rmb:  	rc = __smc_buf_create(smc, is_smcd, true);  	if (rc && smc->conn.sndbuf_desc) {  		down_write(&smc->conn.lgr->sndbufs_lock); -		list_del(&smc->conn.sndbuf_desc->list); +		smc_lgr_buf_list_del(smc->conn.lgr, false, +				     smc->conn.sndbuf_desc);  		up_write(&smc->conn.lgr->sndbufs_lock);  		smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc);  		smc->conn.sndbuf_desc = NULL; diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index d93cf51dbd7c..0db4e5f79ac4 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h @@ -281,6 +281,8 @@ struct smc_link_group {  	struct rw_semaphore	sndbufs_lock;	/* protects tx buffers */  	struct list_head	rmbs[SMC_RMBE_SIZES];	/* rx buffers */  	struct rw_semaphore	rmbs_lock;	/* protects rx buffers */ +	u64			alloc_sndbufs;	/* stats of tx buffers */ +	u64			alloc_rmbs;	/* stats of rx buffers */  	u8			id[SMC_LGR_ID_SIZE];	/* unique lgr id */  	struct delayed_work	free_work;	/* delayed freeing of an lgr */ diff --git a/net/smc/smc_loopback.h b/net/smc/smc_loopback.h index 6dd4292dae56..04dc6808d2e1 100644 --- a/net/smc/smc_loopback.h +++ b/net/smc/smc_loopback.h @@ -15,7 +15,6 @@  #define _SMC_LOOPBACK_H  #include <linux/device.h> -#include <linux/err.h>  #include <net/smc.h>  #if IS_ENABLED(CONFIG_SMC_LO) diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index 2adb92b8c469..1dd362326c0a 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c @@ -887,9 +887,6 @@ int smc_pnet_net_init(struct net *net)  	smc_pnet_create_pnetids_list(net); -	/* disable handshake limitation by default */ -	net->smc.limit_smc_hs = 0; -  	return 0;  } diff --git a/net/smc/smc_stats.c b/net/smc/smc_stats.c index ca14c0f3a07d..e71b17d1e21c 100644 --- a/net/smc/smc_stats.c +++ b/net/smc/smc_stats.c @@ -218,6 +218,12 @@ static int smc_nl_fill_stats_tech_data(struct sk_buff *skb,  			      smc_tech->tx_bytes,  			      SMC_NLA_STATS_PAD))  		goto errattr; +	if (nla_put_uint(skb, SMC_NLA_STATS_T_RX_RMB_USAGE, +			 smc_tech->rx_rmbuse)) +		goto errattr; +	if (nla_put_uint(skb, SMC_NLA_STATS_T_TX_RMB_USAGE, +			 smc_tech->tx_rmbuse)) +		goto errattr;  	if (nla_put_u64_64bit(skb, SMC_NLA_STATS_T_RX_CNT,  			      smc_tech->rx_cnt,  			      SMC_NLA_STATS_PAD)) diff --git a/net/smc/smc_stats.h b/net/smc/smc_stats.h index e19177ce4092..571f9d9e7814 100644 --- a/net/smc/smc_stats.h +++ b/net/smc/smc_stats.h @@ -79,6 +79,8 @@ struct smc_stats_tech {  	u64			tx_bytes;  	u64			rx_cnt;  	u64			tx_cnt; +	u64			rx_rmbuse; +	u64			tx_rmbuse;  };  struct smc_stats { @@ -135,38 +137,46 @@ do { \  } \  while (0) -#define SMC_STAT_RMB_SIZE_SUB(_smc_stats, _tech, k, _len) \ +#define SMC_STAT_RMB_SIZE_SUB(_smc_stats, _tech, k, _is_add, _len) \  do { \ +	typeof(_smc_stats) stats = (_smc_stats); \ +	typeof(_is_add) is_a = (_is_add); \  	typeof(_len) _l = (_len); \  	typeof(_tech) t = (_tech); \  	int _pos; \  	int m = SMC_BUF_MAX - 1; \  	if (_l <= 0) \  		break; \ -	_pos = fls((_l - 1) >> 13); \ -	_pos = (_pos <= m) ? _pos : m; \ -	this_cpu_inc((*(_smc_stats)).smc[t].k ## _rmbsize.buf[_pos]); \ +	if (is_a) { \ +		_pos = fls((_l - 1) >> 13); \ +		_pos = (_pos <= m) ? _pos : m; \ +		this_cpu_inc((*stats).smc[t].k ## _rmbsize.buf[_pos]); \ +		this_cpu_add((*stats).smc[t].k ## _rmbuse, _l); \ +	} else { \ +		this_cpu_sub((*stats).smc[t].k ## _rmbuse, _l); \ +	} \  } \  while (0)  #define SMC_STAT_RMB_SUB(_smc_stats, type, t, key) \  	this_cpu_inc((*(_smc_stats)).smc[t].rmb ## _ ## key.type ## _cnt) -#define SMC_STAT_RMB_SIZE(_smc, _is_smcd, _is_rx, _len) \ +#define SMC_STAT_RMB_SIZE(_smc, _is_smcd, _is_rx, _is_add, _len) \  do { \  	struct net *_net = sock_net(&(_smc)->sk); \  	struct smc_stats __percpu *_smc_stats = _net->smc.smc_stats; \ +	typeof(_is_add) is_add = (_is_add); \  	typeof(_is_smcd) is_d = (_is_smcd); \  	typeof(_is_rx) is_r = (_is_rx); \  	typeof(_len) l = (_len); \  	if ((is_d) && (is_r)) \ -		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_D, rx, l); \ +		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_D, rx, is_add, l); \  	if ((is_d) && !(is_r)) \ -		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_D, tx, l); \ +		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_D, tx, is_add, l); \  	if (!(is_d) && (is_r)) \ -		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_R, rx, l); \ +		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_R, rx, is_add, l); \  	if (!(is_d) && !(is_r)) \ -		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_R, tx, l); \ +		SMC_STAT_RMB_SIZE_SUB(_smc_stats, SMC_TYPE_R, tx, is_add, l); \  } \  while (0) diff --git a/net/smc/smc_sysctl.c b/net/smc/smc_sysctl.c index 13f2bc092db1..2fab6456f765 100644 --- a/net/smc/smc_sysctl.c +++ b/net/smc/smc_sysctl.c @@ -90,6 +90,15 @@ static struct ctl_table smc_table[] = {  		.extra1		= &conns_per_lgr_min,  		.extra2		= &conns_per_lgr_max,  	}, +	{ +		.procname	= "limit_smc_hs", +		.data		= &init_net.smc.limit_smc_hs, +		.maxlen		= sizeof(int), +		.mode		= 0644, +		.proc_handler	= proc_dointvec_minmax, +		.extra1		= SYSCTL_ZERO, +		.extra2		= SYSCTL_ONE, +	},  };  int __net_init smc_sysctl_net_init(struct net *net) @@ -121,6 +130,8 @@ int __net_init smc_sysctl_net_init(struct net *net)  	WRITE_ONCE(net->smc.sysctl_rmem, net_smc_rmem_init);  	net->smc.sysctl_max_links_per_lgr = SMC_LINKS_PER_LGR_MAX_PREFER;  	net->smc.sysctl_max_conns_per_lgr = SMC_CONN_PER_LGR_PREFER; +	/* disable handshake limitation by default */ +	net->smc.limit_smc_hs = 0;  	return 0; | 
