Commit 002dba13 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Jakub Kicinski
Browse files

ipv6: Revert two per-cpu var allocation for RTM_NEWROUTE.



These two commits preallocated two per-cpu variables in
ip6_route_info_create() as fib_nh_common_init() and fib6_nh_init()
were expected to be called under RCU.

  * commit d27b9c40 ("ipv6: Preallocate nhc_pcpu_rth_output in
    ip6_route_info_create().")
  * commit 5720a328 ("ipv6: Preallocate rt->fib6_nh->rt6i_pcpu in
    ip6_route_info_create().")

Now these functions can be called without RCU and can use GFP_KERNEL.

Let's revert the commits.

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent d465bd07
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -617,12 +617,10 @@ 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;
+3 −31
Original line number Diff line number Diff line
@@ -3674,13 +3674,11 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
		goto out;

pcpu_alloc:
	if (!fib6_nh->rt6i_pcpu) {
	fib6_nh->rt6i_pcpu = alloc_percpu_gfp(struct rt6_info *, gfp_flags);
	if (!fib6_nh->rt6i_pcpu) {
		err = -ENOMEM;
		goto out;
	}
	}

	fib6_nh->fib_nh_dev = dev;
	fib6_nh->fib_nh_oif = dev->ifindex;
@@ -3739,24 +3737,6 @@ 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;
}

static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
					       gfp_t gfp_flags,
					       struct netlink_ext_ack *extack)
@@ -3794,12 +3774,6 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
		goto free;
	}

	if (!cfg->fc_nh_id) {
		err = fib6_nh_prealloc_percpu(&rt->fib6_nh[0], gfp_flags);
		if (err)
			goto free_metrics;
	}

	if (cfg->fc_flags & RTF_ADDRCONF)
		rt->dst_nocount = true;

@@ -3824,8 +3798,6 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
	rt->fib6_src.plen = cfg->fc_src_len;
#endif
	return rt;
free_metrics:
	ip_fib_metrics_put(rt->fib6_metrics);
free:
	kfree(rt);
err: