diff options
Diffstat (limited to 'include/net/dst.h')
| -rw-r--r-- | include/net/dst.h | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 307073eae7f8..10b73fb45117 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -95,8 +95,19 @@ struct dst_entry { #ifdef CONFIG_64BIT struct lwtunnel_state *lwtstate; #endif +#ifdef CONFIG_NET_DEV_REFCNT_TRACKER + atomic_t dst_trace_seq; +#endif }; +#ifdef CONFIG_NET_DEV_REFCNT_TRACKER +void save_dst_trace_buffer(struct dst_entry *dst, int delta); +void dump_dst_trace_buffer(const struct net_device *dev); +#else +static inline void save_dst_trace_buffer(struct dst_entry *dst, int delta) { }; +static inline void dump_dst_trace_buffer(const struct net_device *dev) { }; +#endif + struct dst_metrics { u32 metrics[RTAX_MAX]; refcount_t refcnt; @@ -244,7 +255,10 @@ static inline void dst_hold(struct dst_entry *dst) * the placement of __rcuref in struct dst_entry */ BUILD_BUG_ON(offsetof(struct dst_entry, __rcuref) & 63); - WARN_ON(!rcuref_get(&dst->__rcuref)); + if (!rcuref_get(&dst->__rcuref)) + WARN_ON(1); + else + save_dst_trace_buffer(dst, 1); } static inline void dst_use_noref(struct dst_entry *dst, unsigned long time) @@ -308,7 +322,11 @@ static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb */ static inline bool dst_hold_safe(struct dst_entry *dst) { - return rcuref_get(&dst->__rcuref); + const bool ret = rcuref_get(&dst->__rcuref); + + if (ret) + save_dst_trace_buffer(dst, 1); + return ret; } /** |
