net: skb_free_datagram_locked() doesnt drop all packets

dropwatch wrongly diagnose all received UDP packets as drops.

This patch removes trace_kfree_skb() done in skb_free_datagram_locked().

Locations calling skb_free_datagram_locked() should do it on their own.

As a result, drops are accounted on the right function.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Eric Dumazet 2012-06-27 00:23:44 +00:00 committed by David S. Miller
parent 4c3af034fa
commit 22911fc581
4 changed files with 15 additions and 11 deletions

View File

@ -248,7 +248,6 @@ void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
unlock_sock_fast(sk, slow); unlock_sock_fast(sk, slow);
/* skb is now orphaned, can be freed outside of locked section */ /* skb is now orphaned, can be freed outside of locked section */
trace_kfree_skb(skb, skb_free_datagram_locked);
__kfree_skb(skb); __kfree_skb(skb);
} }
EXPORT_SYMBOL(skb_free_datagram_locked); EXPORT_SYMBOL(skb_free_datagram_locked);

View File

@ -108,6 +108,7 @@
#include <net/xfrm.h> #include <net/xfrm.h>
#include <trace/events/udp.h> #include <trace/events/udp.h>
#include <linux/static_key.h> #include <linux/static_key.h>
#include <trace/events/skb.h>
#include "udp_impl.h" #include "udp_impl.h"
struct udp_table udp_table __read_mostly; struct udp_table udp_table __read_mostly;
@ -1220,8 +1221,10 @@ try_again:
goto csum_copy_err; goto csum_copy_err;
} }
if (err) if (unlikely(err)) {
trace_kfree_skb(skb, udp_recvmsg);
goto out_free; goto out_free;
}
if (!peeked) if (!peeked)
UDP_INC_STATS_USER(sock_net(sk), UDP_INC_STATS_USER(sock_net(sk),

View File

@ -48,6 +48,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <trace/events/skb.h>
#include "udp_impl.h" #include "udp_impl.h"
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
@ -385,15 +386,16 @@ try_again:
if (skb_csum_unnecessary(skb)) if (skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied ); msg->msg_iov, copied);
else { else {
err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
if (err == -EINVAL) if (err == -EINVAL)
goto csum_copy_err; goto csum_copy_err;
} }
if (err) if (unlikely(err)) {
trace_kfree_skb(skb, udpv6_recvmsg);
goto out_free; goto out_free;
}
if (!peeked) { if (!peeked) {
if (is_udp4) if (is_udp4)
UDP_INC_STATS_USER(sock_net(sk), UDP_INC_STATS_USER(sock_net(sk),

View File

@ -43,6 +43,7 @@
#include <net/tcp_states.h> #include <net/tcp_states.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/ioctls.h> #include <asm/ioctls.h>
#include <trace/events/skb.h>
#include <linux/sunrpc/types.h> #include <linux/sunrpc/types.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
@ -619,6 +620,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
if (!svc_udp_get_dest_address(rqstp, cmh)) { if (!svc_udp_get_dest_address(rqstp, cmh)) {
net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",
cmh->cmsg_level, cmh->cmsg_type); cmh->cmsg_level, cmh->cmsg_type);
out_free:
trace_kfree_skb(skb, svc_udp_recvfrom);
skb_free_datagram_locked(svsk->sk_sk, skb); skb_free_datagram_locked(svsk->sk_sk, skb);
return 0; return 0;
} }
@ -630,8 +633,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) {
local_bh_enable(); local_bh_enable();
/* checksum error */ /* checksum error */
skb_free_datagram_locked(svsk->sk_sk, skb); goto out_free;
return 0;
} }
local_bh_enable(); local_bh_enable();
skb_free_datagram_locked(svsk->sk_sk, skb); skb_free_datagram_locked(svsk->sk_sk, skb);
@ -640,10 +642,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
rqstp->rq_arg.head[0].iov_base = skb->data + rqstp->rq_arg.head[0].iov_base = skb->data +
sizeof(struct udphdr); sizeof(struct udphdr);
rqstp->rq_arg.head[0].iov_len = len; rqstp->rq_arg.head[0].iov_len = len;
if (skb_checksum_complete(skb)) { if (skb_checksum_complete(skb))
skb_free_datagram_locked(svsk->sk_sk, skb); goto out_free;
return 0;
}
rqstp->rq_xprt_ctxt = skb; rqstp->rq_xprt_ctxt = skb;
} }