Subject: node-aware skb allocation Note: needs benchmarking to prove a gain. Note2: Needs to API rework before upstream submission Signed-off-by: Christoph Hellwig Index: linux-2.6/include/linux/skbuff.h =================================================================== --- linux-2.6.orig/include/linux/skbuff.h +++ linux-2.6/include/linux/skbuff.h @@ -330,17 +330,17 @@ struct sk_buff { extern void kfree_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct sk_buff *__alloc_skb(unsigned int size, - gfp_t priority, int fclone); + gfp_t priority, int fclone, int node); static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 0); + return __alloc_skb(size, priority, 0, -1); } static inline struct sk_buff *alloc_skb_fclone(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 1); + return __alloc_skb(size, priority, 1, -1); } extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, @@ -1107,6 +1107,15 @@ static inline struct sk_buff *__dev_allo return skb; } +static inline struct sk_buff *dev_alloc_skb_node(unsigned int length, int node) +{ + struct sk_buff *skb = __alloc_skb(length + NET_SKB_PAD, + GFP_ATOMIC, 0, node); + if (likely(skb)) + skb_reserve(skb, NET_SKB_PAD); + return skb; +} + /** * dev_alloc_skb - allocate an skbuff for receiving * @length: length to allocate Index: linux-2.6/net/core/skbuff.c =================================================================== --- linux-2.6.orig/net/core/skbuff.c +++ linux-2.6/net/core/skbuff.c @@ -131,6 +131,7 @@ EXPORT_SYMBOL(skb_truesize_bug); * @gfp_mask: allocation mask * @fclone: allocate from fclone cache instead of head cache * and allocate a cloned (child) skb + * @node: numa node to allocate memory on * * Allocate a new &sk_buff. The returned buffer has no headroom and a * tail room of size bytes. The object has a reference count of one. @@ -140,7 +141,7 @@ EXPORT_SYMBOL(skb_truesize_bug); * %GFP_ATOMIC. */ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, - int fclone) + int fclone, int node) { kmem_cache_t *cache; struct skb_shared_info *shinfo; @@ -150,13 +151,15 @@ struct sk_buff *__alloc_skb(unsigned int cache = fclone ? skbuff_fclone_cache : skbuff_head_cache; /* Get the HEAD */ - skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA); + skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); if (!skb) goto out; /* Get the DATA. Size must match skb_add_mtu(). */ size = SKB_DATA_ALIGN(size); - data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); +// data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); + data = kmalloc_node(size + sizeof(struct skb_shared_info), + gfp_mask, node); if (!data) goto nodata;