Commit d27b9c40 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Paolo Abeni
Browse files

ipv6: Preallocate nhc_pcpu_rth_output in ip6_route_info_create().



ip6_route_info_create_nh() will be called under RCU.

It calls fib_nh_common_init() and allocates nhc->nhc_pcpu_rth_output.

As with the reason for rt->fib6_nh->rt6i_pcpu, we want to avoid
GFP_ATOMIC allocation for nhc->nhc_pcpu_rth_output under RCU.

Let's preallocate it in ip6_route_info_create().

Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250418000443.43734-9-kuniyu@amazon.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 5720a328
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -617,10 +617,12 @@ int fib_nh_common_init(struct net *net, struct fib_nh_common *nhc,
{
	int err;

	if (!nhc->nhc_pcpu_rth_output) {
		nhc->nhc_pcpu_rth_output = alloc_percpu_gfp(struct rtable __rcu *,
							    gfp_flags);
		if (!nhc->nhc_pcpu_rth_output)
			return -ENOMEM;
	}

	if (encap) {
		struct lwtunnel_state *lwtstate;
+9 −0
Original line number Diff line number Diff line
@@ -3732,10 +3732,19 @@ void fib6_nh_release_dsts(struct fib6_nh *fib6_nh)

static int fib6_nh_prealloc_percpu(struct fib6_nh *fib6_nh, gfp_t gfp_flags)
{
	struct fib_nh_common *nhc = &fib6_nh->nh_common;

	fib6_nh->rt6i_pcpu = alloc_percpu_gfp(struct rt6_info *, gfp_flags);
	if (!fib6_nh->rt6i_pcpu)
		return -ENOMEM;

	nhc->nhc_pcpu_rth_output = alloc_percpu_gfp(struct rtable __rcu *,
						    gfp_flags);
	if (!nhc->nhc_pcpu_rth_output) {
		free_percpu(fib6_nh->rt6i_pcpu);
		return -ENOMEM;
	}

	return 0;
}