mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	net: add rx_sk to trace_kfree_skb
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>
This commit is contained in:
		
							parent
							
								
									6f46fc9bc2
								
							
						
					
					
						commit
						c53795d48e
					
				
					 4 changed files with 15 additions and 9 deletions
				
			
		|  | @ -24,13 +24,14 @@ DEFINE_DROP_REASON(FN, FN) | ||||||
| TRACE_EVENT(kfree_skb, | TRACE_EVENT(kfree_skb, | ||||||
| 
 | 
 | ||||||
| 	TP_PROTO(struct sk_buff *skb, void *location, | 	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( | 	TP_STRUCT__entry( | ||||||
| 		__field(void *,		skbaddr) | 		__field(void *,		skbaddr) | ||||||
| 		__field(void *,		location) | 		__field(void *,		location) | ||||||
|  | 		__field(void *,		rx_sk) | ||||||
| 		__field(unsigned short,	protocol) | 		__field(unsigned short,	protocol) | ||||||
| 		__field(enum skb_drop_reason,	reason) | 		__field(enum skb_drop_reason,	reason) | ||||||
| 	), | 	), | ||||||
|  | @ -38,12 +39,14 @@ TRACE_EVENT(kfree_skb, | ||||||
| 	TP_fast_assign( | 	TP_fast_assign( | ||||||
| 		__entry->skbaddr = skb; | 		__entry->skbaddr = skb; | ||||||
| 		__entry->location = location; | 		__entry->location = location; | ||||||
|  | 		__entry->rx_sk = rx_sk; | ||||||
| 		__entry->protocol = ntohs(skb->protocol); | 		__entry->protocol = ntohs(skb->protocol); | ||||||
| 		__entry->reason = reason; | 		__entry->reason = reason; | ||||||
| 	), | 	), | ||||||
| 
 | 
 | ||||||
| 	TP_printk("skbaddr=%p protocol=%u location=%pS reason: %s", | 	TP_printk("skbaddr=%p rx_sk=%p protocol=%u location=%pS reason: %s", | ||||||
| 		  __entry->skbaddr, __entry->protocol, __entry->location, | 		  __entry->skbaddr, __entry->rx_sk, __entry->protocol, | ||||||
|  | 		  __entry->location, | ||||||
| 		  __print_symbolic(__entry->reason, | 		  __print_symbolic(__entry->reason, | ||||||
| 				   DEFINE_DROP_REASON(FN, FNe))) | 				   DEFINE_DROP_REASON(FN, FNe))) | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | @ -5234,7 +5234,7 @@ static __latent_entropy void net_tx_action(struct softirq_action *h) | ||||||
| 				trace_consume_skb(skb, net_tx_action); | 				trace_consume_skb(skb, net_tx_action); | ||||||
| 			else | 			else | ||||||
| 				trace_kfree_skb(skb, net_tx_action, | 				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) | 			if (skb->fclone != SKB_FCLONE_UNAVAILABLE) | ||||||
| 				__kfree_skb(skb); | 				__kfree_skb(skb); | ||||||
|  |  | ||||||
|  | @ -109,7 +109,8 @@ static u32 net_dm_queue_len = 1000; | ||||||
| struct net_dm_alert_ops { | struct net_dm_alert_ops { | ||||||
| 	void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb, | 	void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb, | ||||||
| 				void *location, | 				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, | 	void (*napi_poll_probe)(void *ignore, struct napi_struct *napi, | ||||||
| 				int work, int budget); | 				int work, int budget); | ||||||
| 	void (*work_item_func)(struct work_struct *work); | 	void (*work_item_func)(struct work_struct *work); | ||||||
|  | @ -264,7 +265,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location) | ||||||
| 
 | 
 | ||||||
| static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, | static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, | ||||||
| 				void *location, | 				void *location, | ||||||
| 				enum skb_drop_reason reason) | 				enum skb_drop_reason reason, | ||||||
|  | 				struct sock *rx_sk) | ||||||
| { | { | ||||||
| 	trace_drop_common(skb, location); | 	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, | static void net_dm_packet_trace_kfree_skb_hit(void *ignore, | ||||||
| 					      struct sk_buff *skb, | 					      struct sk_buff *skb, | ||||||
| 					      void *location, | 					      void *location, | ||||||
| 					      enum skb_drop_reason reason) | 					      enum skb_drop_reason reason, | ||||||
|  | 					      struct sock *rx_sk) | ||||||
| { | { | ||||||
| 	ktime_t tstamp = ktime_get_real(); | 	ktime_t tstamp = ktime_get_real(); | ||||||
| 	struct per_cpu_dm_data *data; | 	struct per_cpu_dm_data *data; | ||||||
|  |  | ||||||
|  | @ -1203,7 +1203,7 @@ 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); | 		trace_kfree_skb(skb, __builtin_return_address(0), reason, NULL); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Yan Zhai
						Yan Zhai