net: dst: add net device refcount tracking to dst_entry
We want to track all dev_hold()/dev_put() to ease leak hunting. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
4dbd24f65c
commit
9038c32000
@ -3883,6 +3883,23 @@ static inline void dev_put_track(struct net_device *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void dev_replace_track(struct net_device *odev,
|
||||||
|
struct net_device *ndev,
|
||||||
|
netdevice_tracker *tracker,
|
||||||
|
gfp_t gfp)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NET_DEV_REFCNT_TRACKER
|
||||||
|
if (odev)
|
||||||
|
ref_tracker_free(&odev->refcnt_tracker, tracker);
|
||||||
|
#endif
|
||||||
|
dev_hold(ndev);
|
||||||
|
dev_put(odev);
|
||||||
|
#ifdef CONFIG_NET_DEV_REFCNT_TRACKER
|
||||||
|
if (ndev)
|
||||||
|
ref_tracker_alloc(&ndev->refcnt_tracker, tracker, gfp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Carrier loss detection, dial on demand. The functions netif_carrier_on
|
/* Carrier loss detection, dial on demand. The functions netif_carrier_on
|
||||||
* and _off may be called from IRQ context, but it is caller
|
* and _off may be called from IRQ context, but it is caller
|
||||||
* who is responsible for serialization of these calls.
|
* who is responsible for serialization of these calls.
|
||||||
|
@ -77,6 +77,7 @@ struct dst_entry {
|
|||||||
#ifndef CONFIG_64BIT
|
#ifndef CONFIG_64BIT
|
||||||
atomic_t __refcnt; /* 32-bit offset 64 */
|
atomic_t __refcnt; /* 32-bit offset 64 */
|
||||||
#endif
|
#endif
|
||||||
|
netdevice_tracker dev_tracker;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dst_metrics {
|
struct dst_metrics {
|
||||||
|
@ -49,7 +49,7 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
|
|||||||
unsigned short flags)
|
unsigned short flags)
|
||||||
{
|
{
|
||||||
dst->dev = dev;
|
dst->dev = dev;
|
||||||
dev_hold(dev);
|
dev_hold_track(dev, &dst->dev_tracker, GFP_ATOMIC);
|
||||||
dst->ops = ops;
|
dst->ops = ops;
|
||||||
dst_init_metrics(dst, dst_default_metrics.metrics, true);
|
dst_init_metrics(dst, dst_default_metrics.metrics, true);
|
||||||
dst->expires = 0UL;
|
dst->expires = 0UL;
|
||||||
@ -117,7 +117,7 @@ struct dst_entry *dst_destroy(struct dst_entry * dst)
|
|||||||
|
|
||||||
if (dst->ops->destroy)
|
if (dst->ops->destroy)
|
||||||
dst->ops->destroy(dst);
|
dst->ops->destroy(dst);
|
||||||
dev_put(dst->dev);
|
dev_put_track(dst->dev, &dst->dev_tracker);
|
||||||
|
|
||||||
lwtstate_put(dst->lwtstate);
|
lwtstate_put(dst->lwtstate);
|
||||||
|
|
||||||
@ -159,8 +159,8 @@ void dst_dev_put(struct dst_entry *dst)
|
|||||||
dst->input = dst_discard;
|
dst->input = dst_discard;
|
||||||
dst->output = dst_discard_out;
|
dst->output = dst_discard_out;
|
||||||
dst->dev = blackhole_netdev;
|
dst->dev = blackhole_netdev;
|
||||||
dev_hold(dst->dev);
|
dev_replace_track(dev, blackhole_netdev, &dst->dev_tracker,
|
||||||
dev_put(dev);
|
GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dst_dev_put);
|
EXPORT_SYMBOL(dst_dev_put);
|
||||||
|
|
||||||
|
@ -1531,8 +1531,9 @@ void rt_flush_dev(struct net_device *dev)
|
|||||||
if (rt->dst.dev != dev)
|
if (rt->dst.dev != dev)
|
||||||
continue;
|
continue;
|
||||||
rt->dst.dev = blackhole_netdev;
|
rt->dst.dev = blackhole_netdev;
|
||||||
dev_hold(rt->dst.dev);
|
dev_replace_track(dev, blackhole_netdev,
|
||||||
dev_put(dev);
|
&rt->dst.dev_tracker,
|
||||||
|
GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&ul->lock);
|
spin_unlock_bh(&ul->lock);
|
||||||
}
|
}
|
||||||
@ -2819,7 +2820,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
|
|||||||
new->output = dst_discard_out;
|
new->output = dst_discard_out;
|
||||||
|
|
||||||
new->dev = net->loopback_dev;
|
new->dev = net->loopback_dev;
|
||||||
dev_hold(new->dev);
|
dev_hold_track(new->dev, &new->dev_tracker, GFP_ATOMIC);
|
||||||
|
|
||||||
rt->rt_is_input = ort->rt_is_input;
|
rt->rt_is_input = ort->rt_is_input;
|
||||||
rt->rt_iif = ort->rt_iif;
|
rt->rt_iif = ort->rt_iif;
|
||||||
|
@ -182,8 +182,9 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
|
|||||||
|
|
||||||
if (rt_dev == dev) {
|
if (rt_dev == dev) {
|
||||||
rt->dst.dev = blackhole_netdev;
|
rt->dst.dev = blackhole_netdev;
|
||||||
dev_hold(rt->dst.dev);
|
dev_replace_track(rt_dev, blackhole_netdev,
|
||||||
dev_put(rt_dev);
|
&rt->dst.dev_tracker,
|
||||||
|
GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&ul->lock);
|
spin_unlock_bh(&ul->lock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user