mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
ipv4: fib: Allocate fib_info_hash[] during netns initialisation.
We will allocate fib_info_hash[] and fib_info_laddrhash[] for each netns. Currently, fib_info_hash[] is allocated when the first route is added. Let's move the first allocation to a new __net_init function. Note that we must call fib4_semantics_exit() in fib_net_exit_batch() because ->exit() is called earlier than ->exit_batch(). Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20250228042328.96624-4-kuniyu@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
fa336adc10
commit
cfc47029fa
@ -162,6 +162,8 @@ struct fib_info {
|
||||
struct fib_nh fib_nh[] __counted_by(fib_nhs);
|
||||
};
|
||||
|
||||
int __net_init fib4_semantics_init(struct net *net);
|
||||
void __net_exit fib4_semantics_exit(struct net *net);
|
||||
|
||||
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
||||
struct fib_rule;
|
||||
|
@ -1615,9 +1615,15 @@ static int __net_init fib_net_init(struct net *net)
|
||||
error = ip_fib_net_init(net);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
error = fib4_semantics_init(net);
|
||||
if (error)
|
||||
goto out_semantics;
|
||||
|
||||
error = nl_fib_lookup_init(net);
|
||||
if (error < 0)
|
||||
goto out_nlfl;
|
||||
|
||||
error = fib_proc_init(net);
|
||||
if (error < 0)
|
||||
goto out_proc;
|
||||
@ -1627,6 +1633,8 @@ out:
|
||||
out_proc:
|
||||
nl_fib_lookup_exit(net);
|
||||
out_nlfl:
|
||||
fib4_semantics_exit(net);
|
||||
out_semantics:
|
||||
rtnl_lock();
|
||||
ip_fib_net_exit(net);
|
||||
rtnl_unlock();
|
||||
@ -1648,6 +1656,9 @@ static void __net_exit fib_net_exit_batch(struct list_head *net_list)
|
||||
ip_fib_net_exit(net);
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
list_for_each_entry(net, net_list, exit_list)
|
||||
fib4_semantics_exit(net);
|
||||
}
|
||||
|
||||
static struct pernet_operations fib_net_ops = {
|
||||
|
@ -1420,28 +1420,21 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
|
||||
}
|
||||
#endif
|
||||
|
||||
err = -ENOBUFS;
|
||||
|
||||
if (fib_info_cnt >= fib_info_hash_size) {
|
||||
unsigned int new_hash_bits = fib_info_hash_bits + 1;
|
||||
struct hlist_head *new_info_hash;
|
||||
unsigned int new_hash_bits;
|
||||
|
||||
if (!fib_info_hash_bits)
|
||||
new_hash_bits = 4;
|
||||
else
|
||||
new_hash_bits = fib_info_hash_bits + 1;
|
||||
|
||||
new_info_hash = fib_info_hash_alloc(new_hash_bits);
|
||||
if (new_info_hash)
|
||||
fib_info_hash_move(new_info_hash, 1 << new_hash_bits);
|
||||
|
||||
if (!fib_info_hash_size)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
fi = kzalloc(struct_size(fi, fib_nh, nhs), GFP_KERNEL);
|
||||
if (!fi)
|
||||
if (!fi) {
|
||||
err = -ENOBUFS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
fi->fib_metrics = ip_fib_metrics_init(cfg->fc_mx, cfg->fc_mx_len, extack);
|
||||
if (IS_ERR(fi->fib_metrics)) {
|
||||
err = PTR_ERR(fi->fib_metrics);
|
||||
@ -1862,7 +1855,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local)
|
||||
struct fib_info *fi;
|
||||
int ret = 0;
|
||||
|
||||
if (!fib_info_laddrhash || local == 0)
|
||||
if (!local)
|
||||
return 0;
|
||||
|
||||
head = fib_info_laddrhash_bucket(net, local);
|
||||
@ -2264,3 +2257,29 @@ check_saddr:
|
||||
fl4->saddr = inet_select_addr(l3mdev, 0, RT_SCOPE_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
int __net_init fib4_semantics_init(struct net *net)
|
||||
{
|
||||
unsigned int hash_bits = 4;
|
||||
|
||||
if (!net_eq(net, &init_net))
|
||||
return 0;
|
||||
|
||||
fib_info_hash = fib_info_hash_alloc(hash_bits);
|
||||
if (!fib_info_hash)
|
||||
return -ENOMEM;
|
||||
|
||||
fib_info_hash_bits = hash_bits;
|
||||
fib_info_hash_size = 1 << hash_bits;
|
||||
fib_info_laddrhash = fib_info_hash + fib_info_hash_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __net_exit fib4_semantics_exit(struct net *net)
|
||||
{
|
||||
if (!net_eq(net, &init_net))
|
||||
return;
|
||||
|
||||
fib_info_hash_free(fib_info_hash);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user