void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) { bool slow; if (likely(atomic_read(&skb->users) == 1)) smp_rmb(); else if (likely(!atomic_dec_and_test(&skb->users))) return; slow = lock_sock_fast(sk); skb_orphan(skb); sk_mem_reclaim_partial(sk); unlock_sock_fast(sk, slow); /* skb is now orphaned, can be freed outside of locked section */ __kfree_skb(skb); }
void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) { bool slow; if (likely(atomic_read(&skb->users) == 1)) smp_rmb(); else if (likely(!atomic_dec_and_test(&skb->users))) return; slow = lock_sock_fast(sk); skb_orphan(skb); sk_mem_reclaim_partial(sk); unlock_sock_fast(sk, slow); trace_kfree_skb(skb, skb_free_datagram_locked); __kfree_skb(skb); }
void __skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb, int len) { bool slow; if (!skb_unref(skb)) { sk_peek_offset_bwd(sk, len); return; } slow = lock_sock_fast(sk); sk_peek_offset_bwd(sk, len); skb_orphan(skb); sk_mem_reclaim_partial(sk); unlock_sock_fast(sk, slow); /* skb is now orphaned, can be freed outside of locked section */ __kfree_skb(skb); }