diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d39f53ef66bb..17b3f70fbbc3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1549,7 +1549,7 @@ extern int	       skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
 							int hlen,
 							struct iovec *iov);
 extern void	       skb_free_datagram(struct sock *sk, struct sk_buff *skb);
-extern void	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
+extern int	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
 					 unsigned int flags);
 extern __wsum	       skb_checksum(const struct sk_buff *skb, int offset,
 				    int len, __wsum csum);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 029b93e246b4..fbd6c76436d0 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -217,20 +217,27 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
  *	This function currently only disables BH when acquiring the
  *	sk_receive_queue lock.  Therefore it must not be used in a
  *	context where that lock is acquired in an IRQ context.
+ *
+ *	It returns 0 if the packet was removed by us.
  */
 
-void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
+int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
 {
+	int err = 0;
+
 	if (flags & MSG_PEEK) {
+		err = -ENOENT;
 		spin_lock_bh(&sk->sk_receive_queue.lock);
 		if (skb == skb_peek(&sk->sk_receive_queue)) {
 			__skb_unlink(skb, &sk->sk_receive_queue);
 			atomic_dec(&skb->users);
+			err = 0;
 		}
 		spin_unlock_bh(&sk->sk_receive_queue.lock);
 	}
 
 	kfree_skb(skb);
+	return err;
 }
 
 EXPORT_SYMBOL(skb_kill_datagram);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d0283b7fcec5..f50de5d5218d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -899,9 +899,8 @@ out:
 	return err;
 
 csum_copy_err:
-	UDP_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
-
-	skb_kill_datagram(sk, skb, flags);
+	if (!skb_kill_datagram(sk, skb, flags))
+		UDP_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
 
 	if (noblock)
 		return -EAGAIN;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 77ab31b99232..87bccec9882a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -207,8 +207,8 @@ out:
 	return err;
 
 csum_copy_err:
-	UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
-	skb_kill_datagram(sk, skb, flags);
+	if (!skb_kill_datagram(sk, skb, flags))
+		UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
 
 	if (flags & MSG_DONTWAIT)
 		return -EAGAIN;