]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: add rx_sk to trace_kfree_skb
authorYan Zhai <yan@cloudflare.com>
Mon, 17 Jun 2024 18:09:04 +0000 (11:09 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Jun 2024 11:44:22 +0000 (12:44 +0100)
skb does not include enough information to find out receiving
sockets/services and netns/containers on packet drops. In theory
skb->dev tells about netns, but it can get cleared/reused, e.g. by TCP
stack for OOO packet lookup. Similarly, skb->sk often identifies a local
sender, and tells nothing about a receiver.

Allow passing an extra receiving socket to the tracepoint to improve
the visibility on receiving drops.

Signed-off-by: Yan Zhai <yan@cloudflare.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/trace/events/skb.h
net/core/dev.c
net/core/drop_monitor.c
net/core/skbuff.c

index 07e0715628ecc6ce02e2f76828817da790e5e966..b877133cd93a80f6b130fab64f334ecdeab8c8fd 100644 (file)
@@ -24,13 +24,14 @@ DEFINE_DROP_REASON(FN, FN)
 TRACE_EVENT(kfree_skb,
 
        TP_PROTO(struct sk_buff *skb, void *location,
-                enum skb_drop_reason reason),
+                enum skb_drop_reason reason, struct sock *rx_sk),
 
-       TP_ARGS(skb, location, reason),
+       TP_ARGS(skb, location, reason, rx_sk),
 
        TP_STRUCT__entry(
                __field(void *,         skbaddr)
                __field(void *,         location)
+               __field(void *,         rx_sk)
                __field(unsigned short, protocol)
                __field(enum skb_drop_reason,   reason)
        ),
@@ -38,12 +39,14 @@ TRACE_EVENT(kfree_skb,
        TP_fast_assign(
                __entry->skbaddr = skb;
                __entry->location = location;
+               __entry->rx_sk = rx_sk;
                __entry->protocol = ntohs(skb->protocol);
                __entry->reason = reason;
        ),
 
-       TP_printk("skbaddr=%p protocol=%u location=%pS reason: %s",
-                 __entry->skbaddr, __entry->protocol, __entry->location,
+       TP_printk("skbaddr=%p rx_sk=%p protocol=%u location=%pS reason: %s",
+                 __entry->skbaddr, __entry->rx_sk, __entry->protocol,
+                 __entry->location,
                  __print_symbolic(__entry->reason,
                                   DEFINE_DROP_REASON(FN, FNe)))
 );
index c361a7b69da86743a0ee81948755c3e6d678c411..093d82bf0e2886d4948f4952353c71c92e3586c6 100644 (file)
@@ -5234,7 +5234,7 @@ static __latent_entropy void net_tx_action(struct softirq_action *h)
                                trace_consume_skb(skb, net_tx_action);
                        else
                                trace_kfree_skb(skb, net_tx_action,
-                                               get_kfree_skb_cb(skb)->reason);
+                                               get_kfree_skb_cb(skb)->reason, NULL);
 
                        if (skb->fclone != SKB_FCLONE_UNAVAILABLE)
                                __kfree_skb(skb);
index 430ed18f8584c1bee13993cf393bdb665dc6c525..2e0ae3328232f159cbd51ed341eeb34dbf08a031 100644 (file)
@@ -109,7 +109,8 @@ static u32 net_dm_queue_len = 1000;
 struct net_dm_alert_ops {
        void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb,
                                void *location,
-                               enum skb_drop_reason reason);
+                               enum skb_drop_reason reason,
+                               struct sock *rx_sk);
        void (*napi_poll_probe)(void *ignore, struct napi_struct *napi,
                                int work, int budget);
        void (*work_item_func)(struct work_struct *work);
@@ -264,7 +265,8 @@ out:
 
 static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb,
                                void *location,
-                               enum skb_drop_reason reason)
+                               enum skb_drop_reason reason,
+                               struct sock *rx_sk)
 {
        trace_drop_common(skb, location);
 }
@@ -491,7 +493,8 @@ static const struct net_dm_alert_ops net_dm_alert_summary_ops = {
 static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
                                              struct sk_buff *skb,
                                              void *location,
-                                             enum skb_drop_reason reason)
+                                             enum skb_drop_reason reason,
+                                             struct sock *rx_sk)
 {
        ktime_t tstamp = ktime_get_real();
        struct per_cpu_dm_data *data;
index c8ac79851cd67954205cf6e8dcad6d246ce17d7e..8973db4eabd4c7df079471707e477231320a7cf1 100644 (file)
@@ -1203,7 +1203,7 @@ bool __kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason)
        if (reason == SKB_CONSUMED)
                trace_consume_skb(skb, __builtin_return_address(0));
        else
-               trace_kfree_skb(skb, __builtin_return_address(0), reason);
+               trace_kfree_skb(skb, __builtin_return_address(0), reason, NULL);
        return true;
 }