Commit 358a1f20 authored by Litao Jiao's avatar Litao Jiao
Browse files

net/smc: Use reserve space when adding struct netns_smc in struct net

sangfor inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I76JHC



--------------------------------

When adding struct netns_smc to struct net, the size of struct net could
change, so use KABI_USE to fix the problem.

Signed-off-by: default avatarLitao Jiao <jiaolitao@sangfor.com.cn>
parent 0b7bbc12
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -192,9 +192,10 @@ struct net {
#endif
	struct sock		*diag_nlsk;
#if IS_ENABLED(CONFIG_SMC)
	struct netns_smc	smc;
#endif
	KABI_USE(1, struct netns_smc *smc)
#else
	KABI_RESERVE(1)
#endif
	KABI_RESERVE(2)
	KABI_RESERVE(3)
	KABI_RESERVE(4)
+2 −2
Original line number Diff line number Diff line
@@ -267,8 +267,8 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
	sk->sk_state = SMC_INIT;
	sk->sk_destruct = smc_destruct;
	sk->sk_protocol = protocol;
	WRITE_ONCE(sk->sk_sndbuf, READ_ONCE(net->smc.sysctl_wmem));
	WRITE_ONCE(sk->sk_rcvbuf, READ_ONCE(net->smc.sysctl_rmem));
	WRITE_ONCE(sk->sk_sndbuf, sysctl_smcr_wmem(net));
	WRITE_ONCE(sk->sk_rcvbuf, sysctl_smcr_rmem(net));
	smc = smc_sk(sk);
	for (i = 0; i < SMC_MAX_TCP_LISTEN_WORKS; i++) {
		smc->tcp_listen_works[i].smc = smc;
+2 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include "smc_cdc.h"
#include "smc_close.h"
#include "smc_ism.h"
#include "smc_sysctl.h"

#define SMC_LGR_NUM_INCR		256
#define SMC_LGR_FREE_DELAY_SERV		(600 * HZ)
@@ -437,7 +438,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
			goto free_wq;
		lgr_list = &smc_lgr_list.list;
		lgr_lock = &smc_lgr_list.lock;
		lgr->buf_type = sock_net(&smc->sk)->smc.sysctl_smcr_buf_type;
		lgr->buf_type = sysctl_smcr_buf_type(sock_net(&smc->sk));
		atomic_inc(&lgr_cnt);
	}
	smc->conn.lgr = lgr;
+1 −0
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ struct smc_rtoken { /* address/key of remote RMB */
};

#define SMC_BUF_MIN_SIZE	16384	/* minimum size of an RMB */
#define SMC_RMB_DEF_SIZE	131072	/* default size of an RMB */
#define SMC_RMBE_SIZES		16	/* number of distinct RMBE sizes */
/* theoretically, the RFC states that largest size would be 512K,
 * i.e. compressed 5 and thus 6 sizes (0..5), despite
+35 −16
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ static int min_rcvbuf = SMC_BUF_MIN_SIZE;
static struct ctl_table smc_table[] = {
	{
		.procname	= "smcr_buf_type",
		.data		= &init_net.smc.sysctl_smcr_buf_type,
		.maxlen		= sizeof(unsigned int),
		.mode		= 0644,
		.proc_handler	= proc_douintvec_minmax,
@@ -33,7 +32,6 @@ static struct ctl_table smc_table[] = {
	},
	{
		.procname	= "wmem",
		.data		= &init_net.smc.sysctl_wmem,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
@@ -41,7 +39,6 @@ static struct ctl_table smc_table[] = {
	},
	{
		.procname	= "rmem",
		.data		= &init_net.smc.sysctl_rmem,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
@@ -50,34 +47,55 @@ static struct ctl_table smc_table[] = {
	{  }
};

int sysctl_smcr_buf_type(struct net *net)
{
	return READ_ONCE(net->smc->sysctl_smcr_buf_type);
}

int sysctl_smcr_wmem(struct net *net)
{
	return READ_ONCE(net->smc->sysctl_wmem);
}

int sysctl_smcr_rmem(struct net *net)
{
	return READ_ONCE(net->smc->sysctl_rmem);
}

int __net_init smc_sysctl_net_init(struct net *net)
{
	struct ctl_table *table;
	int idx;

	table = smc_table;
	net->smc = kmalloc(sizeof(*net->smc), GFP_KERNEL);
	if (!net->smc)
		goto err_alloc;
	if (!net_eq(net, &init_net)) {
		int i;

		table = kmemdup(table, sizeof(smc_table), GFP_KERNEL);
		if (!table)
			goto err_alloc;

		for (i = 0; i < ARRAY_SIZE(smc_table) - 1; i++)
			table[i].data += (void *)net - (void *)&init_net;
			goto err_table;
	}

	net->smc.smc_hdr = register_net_sysctl(net, "net/smc", table);
	if (!net->smc.smc_hdr)
	idx = 0;
	net->smc->sysctl_smcr_buf_type = SMCR_PHYS_CONT_BUFS;
	table[idx++].data = &net->smc->sysctl_smcr_buf_type;
	WRITE_ONCE(net->smc->sysctl_wmem, READ_ONCE(net->ipv4.sysctl_tcp_wmem[1]));
	table[idx++].data = &net->smc->sysctl_wmem;
	WRITE_ONCE(net->smc->sysctl_rmem, READ_ONCE(net->ipv4.sysctl_tcp_rmem[1]));
	table[idx++].data = &net->smc->sysctl_rmem;

	net->smc->smc_hdr = register_net_sysctl(net, "net/smc", table);
	if (!net->smc->smc_hdr)
		goto err_reg;

	net->smc.sysctl_smcr_buf_type = SMCR_PHYS_CONT_BUFS;
	WRITE_ONCE(net->smc.sysctl_wmem, READ_ONCE(net->ipv4.sysctl_tcp_wmem[1]));
	WRITE_ONCE(net->smc.sysctl_rmem, READ_ONCE(net->ipv4.sysctl_tcp_rmem[1]));
	return 0;

err_reg:
	if (!net_eq(net, &init_net))
		kfree(table);
err_table:
	kfree(net->smc);
err_alloc:
	return -ENOMEM;
}
@@ -86,8 +104,9 @@ void __net_exit smc_sysctl_net_exit(struct net *net)
{
	struct ctl_table *table;

	table = net->smc.smc_hdr->ctl_table_arg;
	unregister_net_sysctl_table(net->smc.smc_hdr);
	table = net->smc->smc_hdr->ctl_table_arg;
	unregister_net_sysctl_table(net->smc->smc_hdr);
	if (!net_eq(net, &init_net))
		kfree(table);
	kfree(net->smc);
}
Loading