Message ID | 1345443532-3707-3-git-send-email-kaber@trash.net |
---|---|
State | Not Applicable |
Headers | show |
On Mon, 2012-08-20 at 08:18 +0200, Patrick McHardy wrote: > Add a function to allocate a skbuff head without any data. This will be > used by memory mapped netlink to attached data from the mmaped area to > the skb. > > Additionally change skb_release_all() to check whether the skb has a > data area to allow the skb destructor to clear the data pointer in > case only a head has been allocated. * ... > > +struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) > +{ > + struct sk_buff *skb; > + > + /* Get the HEAD */ > + skb = kmem_cache_alloc_node(skbuff_head_cache, > + gfp_mask & ~__GFP_DMA, node); > + if (!skb) > + goto out; > + prefetchw(skb); > + This prefetch is probably not worth it, since you write on skb on the following memset(). Cpu wont have enough 'time' to take benefit from this hint. > + /* > + * Only clear those fields we need to clear, not those that we will > + * actually initialise below. Hence, don't put any more fields after > + * the tail pointer in struct sk_buff! > + */ > + memset(skb, 0, offsetof(struct sk_buff, tail)); -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 20 Aug 2012, Eric Dumazet wrote: > On Mon, 2012-08-20 at 08:18 +0200, Patrick McHardy wrote: >> Add a function to allocate a skbuff head without any data. This will be >> used by memory mapped netlink to attached data from the mmaped area to >> the skb. >> >> Additionally change skb_release_all() to check whether the skb has a >> data area to allow the skb destructor to clear the data pointer in >> case only a head has been allocated. > > * ... > >> >> +struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) >> +{ >> + struct sk_buff *skb; >> + >> + /* Get the HEAD */ >> + skb = kmem_cache_alloc_node(skbuff_head_cache, >> + gfp_mask & ~__GFP_DMA, node); >> + if (!skb) >> + goto out; >> + prefetchw(skb); >> + > > This prefetch is probably not worth it, since you write on skb on the > following memset(). Cpu wont have enough 'time' to take benefit from > this hint. Right, I remember we talked about that before and I already removed it. Must have forgotten to actually commit that change, thanks! > >> + /* >> + * Only clear those fields we need to clear, not those that we will >> + * actually initialise below. Hence, don't put any more fields after >> + * the tail pointer in struct sk_buff! >> + */ >> + memset(skb, 0, offsetof(struct sk_buff, tail)); -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b33a3a1..93fe80f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -589,6 +589,12 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE); } +extern struct sk_buff *__alloc_skb_head(gfp_t priority, int node); +static inline struct sk_buff *alloc_skb_head(gfp_t priority) +{ + return __alloc_skb_head(priority, -1); +} + extern void skb_recycle(struct sk_buff *skb); extern bool skb_recycle_check(struct sk_buff *skb, int skb_size); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index fe00d12..4046f6e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -188,6 +188,34 @@ out: * */ +struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) +{ + struct sk_buff *skb; + + /* Get the HEAD */ + skb = kmem_cache_alloc_node(skbuff_head_cache, + gfp_mask & ~__GFP_DMA, node); + if (!skb) + goto out; + prefetchw(skb); + + /* + * Only clear those fields we need to clear, not those that we will + * actually initialise below. Hence, don't put any more fields after + * the tail pointer in struct sk_buff! + */ + memset(skb, 0, offsetof(struct sk_buff, tail)); + skb->data = NULL; + skb->truesize = sizeof(struct sk_buff); + atomic_set(&skb->users, 1); + +#ifdef NET_SKBUFF_DATA_USES_OFFSET + skb->mac_header = ~0U; +#endif +out: + return skb; +} + /** * __alloc_skb - allocate a network buffer * @size: size to allocate @@ -581,7 +609,8 @@ static void skb_release_head_state(struct sk_buff *skb) static void skb_release_all(struct sk_buff *skb) { skb_release_head_state(skb); - skb_release_data(skb); + if (likely(skb->data)) + skb_release_data(skb); } /**
Add a function to allocate a skbuff head without any data. This will be used by memory mapped netlink to attached data from the mmaped area to the skb. Additionally change skb_release_all() to check whether the skb has a data area to allow the skb destructor to clear the data pointer in case only a head has been allocated. Signed-off-by: Patrick McHardy <kaber@trash.net> --- include/linux/skbuff.h | 6 ++++++ net/core/skbuff.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletions(-)