aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
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