aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorWei Wang <weiwan@google.com>2017-06-17 10:42:30 -0700
committerDavid S. Miller <davem@davemloft.net>2017-06-17 22:53:59 -0400
commit95c47f9cf5e028d1ae77dc6c767c1edc8a18025b (patch)
treed8a94c1d8bb6a78c398e71bfecb70458572600ff /net/ipv4/route.c
parentipv4: take dst->__refcnt when caching dst in fib (diff)
downloadlinux-dev-95c47f9cf5e028d1ae77dc6c767c1edc8a18025b.tar.xz
linux-dev-95c47f9cf5e028d1ae77dc6c767c1edc8a18025b.zip
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: Wei Wang <weiwan@google.com> Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3dee0043117e..d986d80258d2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -603,12 +603,14 @@ static void fnhe_flush_routes(struct fib_nh_exception *fnhe)
rt = rcu_dereference(fnhe->fnhe_rth_input);
if (rt) {
RCU_INIT_POINTER(fnhe->fnhe_rth_input, NULL);
+ dst_dev_put(&rt->dst);
dst_release(&rt->dst);
rt_free(rt);
}
rt = rcu_dereference(fnhe->fnhe_rth_output);
if (rt) {
RCU_INIT_POINTER(fnhe->fnhe_rth_output, NULL);
+ dst_dev_put(&rt->dst);
dst_release(&rt->dst);
rt_free(rt);
}
@@ -1337,6 +1339,7 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
dst_hold(&rt->dst);
rcu_assign_pointer(*porig, rt);
if (orig) {
+ dst_dev_put(&orig->dst);
dst_release(&orig->dst);
rt_free(orig);
}
@@ -1369,6 +1372,7 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
prev = cmpxchg(p, orig, rt);
if (prev == orig) {
if (orig) {
+ dst_dev_put(&orig->dst);
dst_release(&orig->dst);
rt_free(orig);
}