Skip to content

Commit

Permalink
net: skb_free_datagram_locked() doesnt drop all packets
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed Jun 27, 2012
1 parent 4c3af03 commit 22911fc
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 11 deletions.
1 change: 0 additions & 1 deletion net/core/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
unlock_sock_fast(sk, slow);

/* skb is now orphaned, can be freed outside of locked section */
trace_kfree_skb(skb, skb_free_datagram_locked);
__kfree_skb(skb);
}
EXPORT_SYMBOL(skb_free_datagram_locked);
Expand Down
5 changes: 4 additions & 1 deletion net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
#include <net/xfrm.h>
#include <trace/events/udp.h>
#include <linux/static_key.h>
#include <trace/events/skb.h>
#include "udp_impl.h"

struct udp_table udp_table __read_mostly;
Expand Down Expand Up @@ -1220,8 +1221,10 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
goto csum_copy_err;
}

if (err)
if (unlikely(err)) {
trace_kfree_skb(skb, udp_recvmsg);
goto out_free;
}

if (!peeked)
UDP_INC_STATS_USER(sock_net(sk),
Expand Down
8 changes: 5 additions & 3 deletions net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <trace/events/skb.h>
#include "udp_impl.h"

int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
Expand Down Expand Up @@ -385,15 +386,16 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,

if (skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied );
msg->msg_iov, copied);
else {
err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
if (err == -EINVAL)
goto csum_copy_err;
}
if (err)
if (unlikely(err)) {
trace_kfree_skb(skb, udpv6_recvmsg);
goto out_free;

}
if (!peeked) {
if (is_udp4)
UDP_INC_STATS_USER(sock_net(sk),
Expand Down
12 changes: 6 additions & 6 deletions net/sunrpc/svcsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <net/tcp_states.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <trace/events/skb.h>

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

Expand Down

0 comments on commit 22911fc

Please sign in to comment.