aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-05-04 02:18:14 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-04 02:18:14 -0400
commit93bb64eac10aad3dae6178d7da94765f207d121f (patch)
tree5f0990ed1a0a9fa9483d828a16235085d5d84215 /net/core
parentf5460618405eec8c3300947a499011528a115acd (diff)
net: skb_free_datagram_locked() fix
Commit 4b0b72f7dd617b ( net: speedup udp receive path ) introduced a bug in skb_free_datagram_locked(). We should not skb_orphan() skb if we dont have the guarantee we are the last skb user, this might happen with MSG_PEEK concurrent users. To keep socket locked for the smallest period of time, we split consume_skb() logic, inlined in skb_free_datagram_locked() Reported-by: Stephen Hemminger <shemminger@vyatta.com> 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/datagram.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 95b851f3d713..e0097531417a 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -229,13 +229,18 @@ EXPORT_SYMBOL(skb_free_datagram);
229 229
230void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) 230void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
231{ 231{
232 if (likely(atomic_read(&skb->users) == 1))
233 smp_rmb();
234 else if (likely(!atomic_dec_and_test(&skb->users)))
235 return;
236
232 lock_sock_bh(sk); 237 lock_sock_bh(sk);
233 skb_orphan(skb); 238 skb_orphan(skb);
234 sk_mem_reclaim_partial(sk); 239 sk_mem_reclaim_partial(sk);
235 unlock_sock_bh(sk); 240 unlock_sock_bh(sk);
236 241
237 /* skb is now orphaned, might be freed outside of locked section */ 242 /* skb is now orphaned, can be freed outside of locked section */
238 consume_skb(skb); 243 __kfree_skb(skb);
239} 244}
240EXPORT_SYMBOL(skb_free_datagram_locked); 245EXPORT_SYMBOL(skb_free_datagram_locked);
241 246