Commit ba8de796 authored by Yan Zhai's avatar Yan Zhai Committed by David S. Miller

net: introduce sk_skb_reason_drop function

Long used destructors kfree_skb and kfree_skb_reason do not pass
receiving socket to packet drop tracepoints trace_kfree_skb.
This makes it hard to track packet drops of a certain netns (container)
or a socket (user application).

The naming of these destructors are also not consistent with most sk/skb
operating functions, i.e. functions named "sk_xxx" or "skb_xxx".
Introduce a new functions sk_skb_reason_drop as drop-in replacement for
kfree_skb_reason on local receiving path. Callers can now pass receiving
sockets to the tracepoints.

kfree_skb and kfree_skb_reason are still usable but they are now just
inline helpers that call sk_skb_reason_drop.

Note it is not feasible to do the same to consume_skb. Packets not
dropped can flow through multiple receive handlers, and have multiple
receiving sockets. Leave it untouched for now.
Suggested-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarYan Zhai <yan@cloudflare.com>
Acked-by: default avatarJesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c53795d4
...@@ -1251,8 +1251,14 @@ static inline bool skb_data_unref(const struct sk_buff *skb, ...@@ -1251,8 +1251,14 @@ static inline bool skb_data_unref(const struct sk_buff *skb,
return true; return true;
} }
void __fix_address void __fix_address sk_skb_reason_drop(struct sock *sk, struct sk_buff *skb,
kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason); enum skb_drop_reason reason);
static inline void
kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason)
{
sk_skb_reason_drop(NULL, skb, reason);
}
/** /**
* kfree_skb - free an sk_buff with 'NOT_SPECIFIED' reason * kfree_skb - free an sk_buff with 'NOT_SPECIFIED' reason
......
...@@ -1190,7 +1190,8 @@ void __kfree_skb(struct sk_buff *skb) ...@@ -1190,7 +1190,8 @@ void __kfree_skb(struct sk_buff *skb)
EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(__kfree_skb);
static __always_inline static __always_inline
bool __kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason) bool __sk_skb_reason_drop(struct sock *sk, struct sk_buff *skb,
enum skb_drop_reason reason)
{ {
if (unlikely(!skb_unref(skb))) if (unlikely(!skb_unref(skb)))
return false; return false;
...@@ -1203,26 +1204,27 @@ bool __kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason) ...@@ -1203,26 +1204,27 @@ bool __kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason)
if (reason == SKB_CONSUMED) if (reason == SKB_CONSUMED)
trace_consume_skb(skb, __builtin_return_address(0)); trace_consume_skb(skb, __builtin_return_address(0));
else else
trace_kfree_skb(skb, __builtin_return_address(0), reason, NULL); trace_kfree_skb(skb, __builtin_return_address(0), reason, sk);
return true; return true;
} }
/** /**
* kfree_skb_reason - free an sk_buff with special reason * sk_skb_reason_drop - free an sk_buff with special reason
* @sk: the socket to receive @skb, or NULL if not applicable
* @skb: buffer to free * @skb: buffer to free
* @reason: reason why this skb is dropped * @reason: reason why this skb is dropped
* *
* Drop a reference to the buffer and free it if the usage count has * Drop a reference to the buffer and free it if the usage count has hit
* hit zero. Meanwhile, pass the drop reason to 'kfree_skb' * zero. Meanwhile, pass the receiving socket and drop reason to
* tracepoint. * 'kfree_skb' tracepoint.
*/ */
void __fix_address void __fix_address
kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason) sk_skb_reason_drop(struct sock *sk, struct sk_buff *skb, enum skb_drop_reason reason)
{ {
if (__kfree_skb_reason(skb, reason)) if (__sk_skb_reason_drop(sk, skb, reason))
__kfree_skb(skb); __kfree_skb(skb);
} }
EXPORT_SYMBOL(kfree_skb_reason); EXPORT_SYMBOL(sk_skb_reason_drop);
#define KFREE_SKB_BULK_SIZE 16 #define KFREE_SKB_BULK_SIZE 16
...@@ -1261,7 +1263,7 @@ kfree_skb_list_reason(struct sk_buff *segs, enum skb_drop_reason reason) ...@@ -1261,7 +1263,7 @@ kfree_skb_list_reason(struct sk_buff *segs, enum skb_drop_reason reason)
while (segs) { while (segs) {
struct sk_buff *next = segs->next; struct sk_buff *next = segs->next;
if (__kfree_skb_reason(segs, reason)) { if (__sk_skb_reason_drop(NULL, segs, reason)) {
skb_poison_list(segs); skb_poison_list(segs);
kfree_skb_add_bulk(segs, &sa, reason); kfree_skb_add_bulk(segs, &sa, reason);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment