consume_skb() isn't for drop or error cases that kfree_skb() is more proper one. At this patch, it fixed tpacket_rcv() and packet_rcv() to be consistent for error or non-error cases letting perf trace its event properly.
Signed-off-by: Weongyo Jeong <weongyo.li...@gmail.com> --- net/packet/af_packet.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1ecfa71..cd100cf 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2040,7 +2040,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct sockaddr_ll *sll; struct packet_sock *po; u8 *skb_head = skb->data; - int skb_len = skb->len; + int err = 0, skb_len = skb->len; unsigned int snaplen, res; if (skb->pkt_type == PACKET_LOOPBACK) @@ -2130,6 +2130,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, return 0; drop_n_acct: + err = -1; spin_lock(&sk->sk_receive_queue.lock); po->stats.stats1.tp_drops++; atomic_inc(&sk->sk_drops); @@ -2141,7 +2142,10 @@ drop_n_restore: skb->len = skb_len; } drop: - consume_skb(skb); + if (!err) + consume_skb(skb); + else + kfree_skb(skb); return 0; } @@ -2153,7 +2157,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct sockaddr_ll *sll; union tpacket_uhdr h; u8 *skb_head = skb->data; - int skb_len = skb->len; + int err = 0, skb_len = skb->len; unsigned int snaplen, res; unsigned long status = TP_STATUS_USER; unsigned short macoff, netoff, hdrlen; @@ -2367,10 +2371,14 @@ drop_n_restore: skb->len = skb_len; } drop: - kfree_skb(skb); + if (!err) + consume_skb(skb); + else + kfree_skb(skb); return 0; drop_n_account: + err = -1; po->stats.stats1.tp_drops++; spin_unlock(&sk->sk_receive_queue.lock); -- 2.1.3