[NET]: Add missing memory barrier to kfree_skb().
Linux Kernel Mailing List <[email protected]>
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
ChangeSet 1.1539.1.4, 2005/02/05 16:56:05-08:00, [email protected] [NET]: Add missing memory barrier to kfree_skb(). Also kill kfree_skb_fast(), that is a relic from fast switching which was killed off years ago. The bug is that in the case where we do the atomic_read() optimization, we need to make sure that reads of skb state later in __kfree_skb() processing (particularly the skb->list BUG check) are not reordered to occur before the counter read by the cpu. Thanks to Olaf Kirch and Anton Blanchard for discovering and helping fix this bug. Signed-off-by: Herbert Xu <[email protected]> Signed-off-by: David S. Miller <[email protected]> skbuff.h | 14 +++++--------- 1 files changed, 5 insertions(+), 9 deletions(-) diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h --- a/include/linux/skbuff.h 2005-02-09 09:06:14 -08:00 +++ b/include/linux/skbuff.h 2005-02-09 09:06:14 -08:00 @@ -290,15 +290,11 @@ static inline void kfree_skb(struct sk_buff *skb) { - if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) - __kfree_skb(skb); -} - -/* Use this if you didn't touch the skb state [for fast switching] */ -static inline void kfree_skb_fast(struct sk_buff *skb) -{ - if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) - kfree_skbmem(skb); + if (likely(atomic_read(&skb->users) == 1)) + smp_rmb(); + else if (likely(!atomic_dec_and_test(&skb->users))) + return; + __kfree_skb(skb); } /**