icmp: Remove some spurious dropped packet profile hits from the ICMP path
Subsystems (3)
PATCH v2 1/1 icmp: Remove some spurious dropped packet profile hits from the ICMP path
From: Rick Jones <[email protected]>
If icmp_rcv() has successfully processed the incoming ICMP datagram, we should use consume_skb() rather than kfree_skb() because a hit on the likes of perf -e skb:kfree_skb is not called-for.
---
A test system hit with a flood ping hits on perf top -e ksb:kfre_skb before the change and none after for the normal/success path. The IPv6 path would be somewhat more ugly. For the time being, just deal with the overlap on ping_rcv() between the two to avoid a possible double free of an skb.
include/net/ping.h +1 -1
@@ -82,7 +82,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,int ping_v6_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len);int ping_queue_rcv_skb (struct sock *sk,struct sk_buff *skb); -void ping_rcv (struct sk_buff *skb); +bool ping_rcv (struct sk_buff *skb);#ifdef CONFIG_PROC_FS struct ping_seq_afinfo {
net/ipv4/icmp.c +28 -15
117 lines not on this page · raw message
net/ipv4/ping.c +3 -3
@@ -955,7 +955,7 @@ EXPORT_SYMBOL_GPL(ping_queue_rcv_skb);* All we need to do is get the socket. */ -void ping_rcv (struct sk_buff *skb) +bool ping_rcv (struct sk_buff *skb) {struct sock *sk;struct net *net =dev_net (skb->dev);
@@ -974,11 +974,11 @@ void ping_rcv(struct sk_buff *skb)pr_debug ("rcv on socket %p\n" , sk);ping_queue_rcv_skb (sk,skb_get (skb));sock_put (sk); -return ; +return true; }pr_debug ("no socket, dropping\n" ); -/* We're called from icmp_rcv(). kfree_skb() is done there. */ +return false; }EXPORT_SYMBOL_GPL (ping_rcv);
net/ipv6/icmp.c +10 -2
@@ -679,6 +679,7 @@ static int icmpv6_rcv(struct sk_buff *skb)const struct in6_addr *saddr, *daddr;struct icmp6hdr *hdr;u8 type; +bool success = false;if (!xfrm6_policy_check (NULL ,XFRM_POLICY_IN , skb)) {struct sec_path *sp =skb_sec_path (skb);
@@ -726,7 +727,7 @@ static int icmpv6_rcv(struct sk_buff *skb)break ;case ICMPV6_ECHO_REPLY : -ping_rcv (skb); + success =ping_rcv (skb);break ;case ICMPV6_PKT_TOOBIG :
@@ -790,7 +791,14 @@ static int icmpv6_rcv(struct sk_buff *skb)icmpv6_notify (skb, type, hdr->icmp6_code, hdr->icmp6_mtu); } -kfree_skb (skb); +/* until the v6 path can be better sorted assume failure and +* preserve the status quo behaviour for the rest of the paths to here +*/ +if (success) +consume_skb (skb); +else +kfree_skb (skb); +return 0 ; csum_error:
David Miller
maintainerFrom: [email protected] (Rick Jones)
Date: Mon, 17 Nov 2014 14:04:29 -0800 (PST)
Quoted 7 lines
From: Rick Jones <[email protected]>
If
icmp_rcv()has successfully processed the incoming ICMP datagram, we should useconsume_skb()rather thankfree_skb()because a hit on the likes of perf -e skb:kfree_skb is not called-for.Signed-off-by Rick Jones <[email protected]>
This looks better, applied, thanks Rick.