summaryrefslogtreecommitdiff
path: root/include/net/dst.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/dst.h')
-rw-r--r--include/net/dst.h22
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;
}
/**