Message ID | 1315070771-18576-3-git-send-email-kaber@trash.net |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Le samedi 03 septembre 2011 à 19:26 +0200, kaber@trash.net a écrit : > +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); Please remove this prefetchw(), since we have no delay between it and actual memset(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)); -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 04.09.2011 10:12, Eric Dumazet wrote: > Le samedi 03 septembre 2011 à 19:26 +0200, kaber@trash.net a écrit : > >> +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); > > Please remove this prefetchw(), since we have no delay between it and > actual memset(skb). Done, thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" 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 7b996ed..8cfc285 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -521,6 +521,12 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, 1, 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 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); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2beda82..d632de9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -153,6 +153,34 @@ static void skb_under_panic(struct sk_buff *skb, int sz, void *here) * */ +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 @@ -414,7 +442,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); } /**