Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95c47f9c authored by Wei Wang's avatar Wei Wang Committed by David S. Miller
Browse files

ipv4: call dst_dev_put() properly



As the intend of this patch series is to completely remove dst gc,
we need to call dst_dev_put() to release the reference to dst->dev
when removing routes from fib because we won't keep the gc list anymore
and will lose the dst pointer right after removing the routes.
Without the gc list, there is no way to find all the dst's that have
dst->dev pointing to the going-down dev.
Hence, we are doing dst_dev_put() immediately before we lose the last
reference of the dst from the routing code. The next dst_check() will
trigger a route re-lookup to find another route (if there is any).

Signed-off-by: default avatarWei Wang <weiwan@google.com>
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0830106c
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,7 @@ static void rt_fibinfo_free(struct rtable __rcu **rtp)
	 * free_fib_info_rcu()
	 * free_fib_info_rcu()
	 */
	 */


	dst_dev_put(&rt->dst);
	dst_release(&rt->dst);
	dst_release(&rt->dst);
	dst_free(&rt->dst);
	dst_free(&rt->dst);
}
}
@@ -196,6 +197,7 @@ static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp)


		rt = rcu_dereference_protected(*per_cpu_ptr(rtp, cpu), 1);
		rt = rcu_dereference_protected(*per_cpu_ptr(rtp, cpu), 1);
		if (rt) {
		if (rt) {
			dst_dev_put(&rt->dst);
			dst_release(&rt->dst);
			dst_release(&rt->dst);
			dst_free(&rt->dst);
			dst_free(&rt->dst);
		}
		}
+4 −0
Original line number Original line Diff line number Diff line
@@ -603,12 +603,14 @@ static void fnhe_flush_routes(struct fib_nh_exception *fnhe)
	rt = rcu_dereference(fnhe->fnhe_rth_input);
	rt = rcu_dereference(fnhe->fnhe_rth_input);
	if (rt) {
	if (rt) {
		RCU_INIT_POINTER(fnhe->fnhe_rth_input, NULL);
		RCU_INIT_POINTER(fnhe->fnhe_rth_input, NULL);
		dst_dev_put(&rt->dst);
		dst_release(&rt->dst);
		dst_release(&rt->dst);
		rt_free(rt);
		rt_free(rt);
	}
	}
	rt = rcu_dereference(fnhe->fnhe_rth_output);
	rt = rcu_dereference(fnhe->fnhe_rth_output);
	if (rt) {
	if (rt) {
		RCU_INIT_POINTER(fnhe->fnhe_rth_output, NULL);
		RCU_INIT_POINTER(fnhe->fnhe_rth_output, NULL);
		dst_dev_put(&rt->dst);
		dst_release(&rt->dst);
		dst_release(&rt->dst);
		rt_free(rt);
		rt_free(rt);
	}
	}
@@ -1337,6 +1339,7 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
			dst_hold(&rt->dst);
			dst_hold(&rt->dst);
			rcu_assign_pointer(*porig, rt);
			rcu_assign_pointer(*porig, rt);
			if (orig) {
			if (orig) {
				dst_dev_put(&orig->dst);
				dst_release(&orig->dst);
				dst_release(&orig->dst);
				rt_free(orig);
				rt_free(orig);
			}
			}
@@ -1369,6 +1372,7 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
	prev = cmpxchg(p, orig, rt);
	prev = cmpxchg(p, orig, rt);
	if (prev == orig) {
	if (prev == orig) {
		if (orig) {
		if (orig) {
			dst_dev_put(&orig->dst);
			dst_release(&orig->dst);
			dst_release(&orig->dst);
			rt_free(orig);
			rt_free(orig);
		}
		}