Message ID | 20250225182250.74650-4-kuniyu@amazon.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | ipv4: fib: Convert RTM_NEWROUTE and RTM_DELROUTE to per-netns RTNL. | expand |
On Tue, Feb 25, 2025 at 7:24 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote: > > 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. > > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Reviewed-by: Eric Dumazet <edumazet@google.com>
On 2/25/25 11:22 AM, Kuniyuki Iwashima wrote: > diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c > index 6730e2034cf8..dbf84c23ca09 100644 > --- a/net/ipv4/fib_frontend.c > +++ b/net/ipv4/fib_frontend.c > @@ -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 @@ static int __net_init fib_net_init(struct net *net) > out_proc: > nl_fib_lookup_exit(net); > out_nlfl: > + fib4_semantics_init(net); _exit?
On Wed, Feb 26, 2025 at 6:48 PM David Ahern <dsahern@kernel.org> wrote: > > On 2/25/25 11:22 AM, Kuniyuki Iwashima wrote: > > diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c > > index 6730e2034cf8..dbf84c23ca09 100644 > > --- a/net/ipv4/fib_frontend.c > > +++ b/net/ipv4/fib_frontend.c > > @@ -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 @@ static int __net_init fib_net_init(struct net *net) > > out_proc: > > nl_fib_lookup_exit(net); > > out_nlfl: > > + fib4_semantics_init(net); > > _exit? Yes, this was mentioned yesterday.
On 2/26/25 11:09 AM, Eric Dumazet wrote: >>> @@ -1627,6 +1633,8 @@ static int __net_init fib_net_init(struct net *net) >>> out_proc: >>> nl_fib_lookup_exit(net); >>> out_nlfl: >>> + fib4_semantics_init(net); >> >> _exit? > > Yes, this was mentioned yesterday. not in this code path but rather fib_net_exit. Hence me pointing out this one only
From: David Ahern <dsahern@kernel.org> Date: Wed, 26 Feb 2025 11:12:13 -0700 > On 2/26/25 11:09 AM, Eric Dumazet wrote: > >>> @@ -1627,6 +1633,8 @@ static int __net_init fib_net_init(struct net *net) > >>> out_proc: > >>> nl_fib_lookup_exit(net); > >>> out_nlfl: > >>> + fib4_semantics_init(net); > >> > >> _exit? > > > > Yes, this was mentioned yesterday. > > not in this code path but rather fib_net_exit. Hence me pointing out > this one only Sorry, actually I realised the path and fixed just after sending the diff yesterday. Will send v2 shortly. Thank you both for the review !
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index a113c11ab56b..e3864b74e92a 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -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; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 6730e2034cf8..dbf84c23ca09 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -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 @@ static int __net_init fib_net_init(struct net *net) out_proc: nl_fib_lookup_exit(net); out_nlfl: + fib4_semantics_init(net); +out_semantics: rtnl_lock(); ip_fib_net_exit(net); rtnl_unlock(); @@ -1637,6 +1645,7 @@ static void __net_exit fib_net_exit(struct net *net) { fib_proc_exit(net); nl_fib_lookup_exit(net); + fib4_semantics_init(net); } static void __net_exit fib_net_exit_batch(struct list_head *net_list) diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index a68a4eb5e0d1..f00ac983861a 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -1421,28 +1421,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); @@ -1863,7 +1856,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); @@ -2265,3 +2258,29 @@ void fib_select_path(struct net *net, struct fib_result *res, 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); +}
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. Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> --- include/net/ip_fib.h | 2 ++ net/ipv4/fib_frontend.c | 9 ++++++++ net/ipv4/fib_semantics.c | 45 ++++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 13 deletions(-)