diff options
author | Andy Fleming <afleming@freescale.com> | 2011-10-13 08:33:54 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-19 23:59:45 +0400 |
commit | 3d153a7c8b23031df35e61377c0600a6c96a8b0b (patch) | |
tree | f5c7f622331728ba12f40c2ebb66666ce3d924fd /include/linux/skbuff.h | |
parent | 1e5c22cde3b85737921d3ec6ecf2c356e5b64ea7 (diff) | |
download | linux-3d153a7c8b23031df35e61377c0600a6c96a8b0b.tar.xz |
net: Allow skb_recycle_check to be done in stages
skb_recycle_check resets the skb if it's eligible for recycling.
However, there are times when a driver might want to optionally
manipulate the skb data with the skb before resetting the skb,
but after it has determined eligibility. We do this by splitting the
eligibility check from the skb reset, creating two inline functions to
accomplish that task.
Signed-off-by: Andy Fleming <afleming@freescale.com>
Acked-by: David Daney <david.daney@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r-- | include/linux/skbuff.h | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6fcbbbd12ceb..77ddf2de712f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -550,6 +550,7 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, 1, NUMA_NO_NODE); } +extern void skb_recycle(struct sk_buff *skb); extern bool skb_recycle_check(struct sk_buff *skb, int skb_size); extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); @@ -2484,5 +2485,25 @@ static inline void skb_checksum_none_assert(struct sk_buff *skb) bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off); +static inline bool skb_is_recycleable(struct sk_buff *skb, int skb_size) +{ + if (irqs_disabled()) + return false; + + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) + return false; + + if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) + return false; + + skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD); + if (skb_end_pointer(skb) - skb->head < skb_size) + return false; + + if (skb_shared(skb) || skb_cloned(skb)) + return false; + + return true; +} #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ |