mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-03 21:45:08 -04:00
Merge branch 'netns-init-cleanups' into main
Kuniyuki Iwashima says: ==================== net: Random cleanup for netns initialisation. patch 1 & 2 suppress unwanted memory allocation for net->gen->ptr[]. patch 3 ~ 6 move part of netns initialisation to prenet_init() that do not require pernet_ops_rwsem. v2: patch 1 : Removed Fixes: tag patch 2 : Use XOR for WARN_ON() v1: https://lore.kernel.org/netdev/20240729210801.16196-1-kuniyu@amazon.com/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -451,8 +451,8 @@ struct pernet_operations {
|
||||
/* Following method is called with RTNL held. */
|
||||
void (*exit_batch_rtnl)(struct list_head *net_exit_list,
|
||||
struct list_head *dev_kill_list);
|
||||
unsigned int *id;
|
||||
size_t size;
|
||||
unsigned int * const id;
|
||||
const size_t size;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -125,7 +125,7 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
|
||||
int err = -ENOMEM;
|
||||
void *data = NULL;
|
||||
|
||||
if (ops->id && ops->size) {
|
||||
if (ops->id) {
|
||||
data = kzalloc(ops->size, GFP_KERNEL);
|
||||
if (!data)
|
||||
goto out;
|
||||
@@ -140,7 +140,7 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
if (ops->id && ops->size) {
|
||||
if (ops->id) {
|
||||
ng = rcu_dereference_protected(net->gen,
|
||||
lockdep_is_held(&pernet_ops_rwsem));
|
||||
ng->ptr[*ops->id] = NULL;
|
||||
@@ -182,7 +182,8 @@ static void ops_free_list(const struct pernet_operations *ops,
|
||||
struct list_head *net_exit_list)
|
||||
{
|
||||
struct net *net;
|
||||
if (ops->size && ops->id) {
|
||||
|
||||
if (ops->id) {
|
||||
list_for_each_entry(net, net_exit_list, exit_list)
|
||||
kfree(net_generic(net, *ops->id));
|
||||
}
|
||||
@@ -308,16 +309,38 @@ struct net *get_net_ns_by_id(const struct net *net, int id)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_net_ns_by_id);
|
||||
|
||||
/* init code that must occur even if setup_net() is not called. */
|
||||
static __net_init void preinit_net(struct net *net)
|
||||
static __net_init void preinit_net_sysctl(struct net *net)
|
||||
{
|
||||
net->core.sysctl_somaxconn = SOMAXCONN;
|
||||
/* Limits per socket sk_omem_alloc usage.
|
||||
* TCP zerocopy regular usage needs 128 KB.
|
||||
*/
|
||||
net->core.sysctl_optmem_max = 128 * 1024;
|
||||
net->core.sysctl_txrehash = SOCK_TXREHASH_ENABLED;
|
||||
}
|
||||
|
||||
/* init code that must occur even if setup_net() is not called. */
|
||||
static __net_init void preinit_net(struct net *net, struct user_namespace *user_ns)
|
||||
{
|
||||
refcount_set(&net->passive, 1);
|
||||
refcount_set(&net->ns.count, 1);
|
||||
ref_tracker_dir_init(&net->refcnt_tracker, 128, "net refcnt");
|
||||
ref_tracker_dir_init(&net->notrefcnt_tracker, 128, "net notrefcnt");
|
||||
|
||||
get_random_bytes(&net->hash_mix, sizeof(u32));
|
||||
net->dev_base_seq = 1;
|
||||
net->user_ns = user_ns;
|
||||
|
||||
idr_init(&net->netns_ids);
|
||||
spin_lock_init(&net->nsid_lock);
|
||||
mutex_init(&net->ipv4.ra_mutex);
|
||||
preinit_net_sysctl(net);
|
||||
}
|
||||
|
||||
/*
|
||||
* setup_net runs the initializers for the network namespace object.
|
||||
*/
|
||||
static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
|
||||
static __net_init int setup_net(struct net *net)
|
||||
{
|
||||
/* Must be called with pernet_ops_rwsem held */
|
||||
const struct pernet_operations *ops, *saved_ops;
|
||||
@@ -325,19 +348,9 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
|
||||
LIST_HEAD(dev_kill_list);
|
||||
int error = 0;
|
||||
|
||||
refcount_set(&net->ns.count, 1);
|
||||
ref_tracker_dir_init(&net->refcnt_tracker, 128, "net refcnt");
|
||||
|
||||
refcount_set(&net->passive, 1);
|
||||
get_random_bytes(&net->hash_mix, sizeof(u32));
|
||||
preempt_disable();
|
||||
net->net_cookie = gen_cookie_next(&net_cookie);
|
||||
preempt_enable();
|
||||
net->dev_base_seq = 1;
|
||||
net->user_ns = user_ns;
|
||||
idr_init(&net->netns_ids);
|
||||
spin_lock_init(&net->nsid_lock);
|
||||
mutex_init(&net->ipv4.ra_mutex);
|
||||
|
||||
list_for_each_entry(ops, &pernet_list, list) {
|
||||
error = ops_init(ops, net);
|
||||
@@ -382,32 +395,6 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int __net_init net_defaults_init_net(struct net *net)
|
||||
{
|
||||
net->core.sysctl_somaxconn = SOMAXCONN;
|
||||
/* Limits per socket sk_omem_alloc usage.
|
||||
* TCP zerocopy regular usage needs 128 KB.
|
||||
*/
|
||||
net->core.sysctl_optmem_max = 128 * 1024;
|
||||
net->core.sysctl_txrehash = SOCK_TXREHASH_ENABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pernet_operations net_defaults_ops = {
|
||||
.init = net_defaults_init_net,
|
||||
};
|
||||
|
||||
static __init int net_defaults_init(void)
|
||||
{
|
||||
if (register_pernet_subsys(&net_defaults_ops))
|
||||
panic("Cannot initialize net default settings");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
core_initcall(net_defaults_init);
|
||||
|
||||
#ifdef CONFIG_NET_NS
|
||||
static struct ucounts *inc_net_namespaces(struct user_namespace *ns)
|
||||
{
|
||||
@@ -496,8 +483,7 @@ struct net *copy_net_ns(unsigned long flags,
|
||||
goto dec_ucounts;
|
||||
}
|
||||
|
||||
preinit_net(net);
|
||||
refcount_set(&net->passive, 1);
|
||||
preinit_net(net, user_ns);
|
||||
net->ucounts = ucounts;
|
||||
get_user_ns(user_ns);
|
||||
|
||||
@@ -505,7 +491,7 @@ struct net *copy_net_ns(unsigned long flags,
|
||||
if (rv < 0)
|
||||
goto put_userns;
|
||||
|
||||
rv = setup_net(net, user_ns);
|
||||
rv = setup_net(net);
|
||||
|
||||
up_read(&pernet_ops_rwsem);
|
||||
|
||||
@@ -1199,9 +1185,10 @@ void __init net_ns_init(void)
|
||||
#ifdef CONFIG_KEYS
|
||||
init_net.key_domain = &init_net_key_domain;
|
||||
#endif
|
||||
preinit_net(&init_net, &init_user_ns);
|
||||
|
||||
down_write(&pernet_ops_rwsem);
|
||||
preinit_net(&init_net);
|
||||
if (setup_net(&init_net, &init_user_ns))
|
||||
if (setup_net(&init_net))
|
||||
panic("Could not setup the initial network namespace");
|
||||
|
||||
init_net_initialized = true;
|
||||
@@ -1244,7 +1231,7 @@ static int __register_pernet_operations(struct list_head *list,
|
||||
LIST_HEAD(net_exit_list);
|
||||
|
||||
list_add_tail(&ops->list, list);
|
||||
if (ops->init || (ops->id && ops->size)) {
|
||||
if (ops->init || ops->id) {
|
||||
/* We held write locked pernet_ops_rwsem, and parallel
|
||||
* setup_net() and cleanup_net() are not possible.
|
||||
*/
|
||||
@@ -1310,6 +1297,9 @@ static int register_pernet_operations(struct list_head *list,
|
||||
{
|
||||
int error;
|
||||
|
||||
if (WARN_ON(!!ops->id ^ !!ops->size))
|
||||
return -EINVAL;
|
||||
|
||||
if (ops->id) {
|
||||
error = ida_alloc_min(&net_generic_ids, MIN_PERNET_OPS_ID,
|
||||
GFP_KERNEL);
|
||||
|
||||
@@ -1393,8 +1393,6 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
|
||||
* L2TPv2, we dump only L2TPv2 tunnels and sessions here.
|
||||
*****************************************************************************/
|
||||
|
||||
static unsigned int pppol2tp_net_id;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
struct pppol2tp_seq_data {
|
||||
@@ -1628,7 +1626,6 @@ static __net_exit void pppol2tp_exit_net(struct net *net)
|
||||
static struct pernet_operations pppol2tp_net_ops = {
|
||||
.init = pppol2tp_init_net,
|
||||
.exit = pppol2tp_exit_net,
|
||||
.id = &pppol2tp_net_id,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
Reference in New Issue
Block a user