aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/skbuff.h
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2014-12-03 20:04:39 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-09 13:40:20 -0500
commit6ffe75eb53564953e75c051e1c28676e1e56f385 (patch)
treedf3ded93cb68f3e739d1c490e8377dfee2fc028a /include/linux/skbuff.h
parent395eea6ccf2b253f81b4718ffbcae67d36fe2e69 (diff)
net: avoid two atomic operations in fast clones
Commit ce1a4ea3f125 ("net: avoid one atomic operation in skb_clone()") took the wrong way to save one atomic operation. It is actually possible to avoid two atomic operations, if we do not change skb->fclone values, and only rely on clone_ref content to signal if the clone is available or not. skb_clone() can simply use the fast clone if clone_ref is 1. kfree_skbmem() can avoid the atomic_dec_and_test() if clone_ref is 1. Note that because we usually free the clone before the original skb, this particular attempt is only done for the original skb to have better branch prediction. SKB_FCLONE_FREE is removed. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Chris Mason <clm@fb.com> Cc: Sabrina Dubroca <sd@queasysnail.net> Cc: Vijay Subramanian <subramanian.vijay@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r--include/linux/skbuff.h3
1 files changed, 1 insertions, 2 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d1e2575000b9..e9281b5b7f59 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -344,7 +344,6 @@ enum {
344 SKB_FCLONE_UNAVAILABLE, /* skb has no fclone (from head_cache) */ 344 SKB_FCLONE_UNAVAILABLE, /* skb has no fclone (from head_cache) */
345 SKB_FCLONE_ORIG, /* orig skb (from fclone_cache) */ 345 SKB_FCLONE_ORIG, /* orig skb (from fclone_cache) */
346 SKB_FCLONE_CLONE, /* companion fclone skb (from fclone_cache) */ 346 SKB_FCLONE_CLONE, /* companion fclone skb (from fclone_cache) */
347 SKB_FCLONE_FREE, /* this companion fclone skb is available */
348}; 347};
349 348
350enum { 349enum {
@@ -818,7 +817,7 @@ static inline bool skb_fclone_busy(const struct sock *sk,
818 fclones = container_of(skb, struct sk_buff_fclones, skb1); 817 fclones = container_of(skb, struct sk_buff_fclones, skb1);
819 818
820 return skb->fclone == SKB_FCLONE_ORIG && 819 return skb->fclone == SKB_FCLONE_ORIG &&
821 fclones->skb2.fclone == SKB_FCLONE_CLONE && 820 atomic_read(&fclones->fclone_ref) > 1 &&
822 fclones->skb2.sk == sk; 821 fclones->skb2.sk == sk;
823} 822}
824 823