aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-06-01 02:44:05 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-01 02:44:05 -0400
commitb1faf5666438090a4dc4fceac8502edc7788b7e3 (patch)
treef90808dea27cc38aff6feed1782e2a5666fa6ee9 /net/core
parentbc284f94f84c3d76e49c6f3df9028c503f9589d9 (diff)
net: sock_queue_err_skb() dont mess with sk_forward_alloc
Correct sk_forward_alloc handling for error_queue would need to use a backlog of frames that softirq handler could not deliver because socket is owned by user thread. Or extend backlog processing to be able to process normal and error packets. Another possibility is to not use mem charge for error queue, this is what I implemented in this patch. Note: this reverts commit 29030374 (net: fix sk_forward_alloc corruptions), since we dont need to lock socket anymore. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skbuff.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4e7ac09c281a..9f07e749d7b1 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2965,6 +2965,34 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
2965} 2965}
2966EXPORT_SYMBOL_GPL(skb_cow_data); 2966EXPORT_SYMBOL_GPL(skb_cow_data);
2967 2967
2968static void sock_rmem_free(struct sk_buff *skb)
2969{
2970 struct sock *sk = skb->sk;
2971
2972 atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
2973}
2974
2975/*
2976 * Note: We dont mem charge error packets (no sk_forward_alloc changes)
2977 */
2978int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
2979{
2980 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
2981 (unsigned)sk->sk_rcvbuf)
2982 return -ENOMEM;
2983
2984 skb_orphan(skb);
2985 skb->sk = sk;
2986 skb->destructor = sock_rmem_free;
2987 atomic_add(skb->truesize, &sk->sk_rmem_alloc);
2988
2989 skb_queue_tail(&sk->sk_error_queue, skb);
2990 if (!sock_flag(sk, SOCK_DEAD))
2991 sk->sk_data_ready(sk, skb->len);
2992 return 0;
2993}
2994EXPORT_SYMBOL(sock_queue_err_skb);
2995
2968void skb_tstamp_tx(struct sk_buff *orig_skb, 2996void skb_tstamp_tx(struct sk_buff *orig_skb,
2969 struct skb_shared_hwtstamps *hwtstamps) 2997 struct skb_shared_hwtstamps *hwtstamps)
2970{ 2998{
@@ -2997,9 +3025,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
2997 serr->ee.ee_errno = ENOMSG; 3025 serr->ee.ee_errno = ENOMSG;
2998 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; 3026 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
2999 3027
3000 bh_lock_sock(sk);
3001 err = sock_queue_err_skb(sk, skb); 3028 err = sock_queue_err_skb(sk, skb);
3002 bh_unlock_sock(sk);
3003 3029
3004 if (err) 3030 if (err)
3005 kfree_skb(skb); 3031 kfree_skb(skb);