aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c73
1 files changed, 40 insertions, 33 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 46a3d23d259e..368f65c15e4f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -160,8 +160,8 @@ static void skb_under_panic(struct sk_buff *skb, int sz, void *here)
160 * @node: numa node to allocate memory on 160 * @node: numa node to allocate memory on
161 * 161 *
162 * Allocate a new &sk_buff. The returned buffer has no headroom and a 162 * Allocate a new &sk_buff. The returned buffer has no headroom and a
163 * tail room of size bytes. The object has a reference count of one. 163 * tail room of at least size bytes. The object has a reference count
164 * The return is the buffer. On a failure the return is %NULL. 164 * of one. The return is the buffer. On a failure the return is %NULL.
165 * 165 *
166 * Buffers may only be allocated from interrupts using a @gfp_mask of 166 * Buffers may only be allocated from interrupts using a @gfp_mask of
167 * %GFP_ATOMIC. 167 * %GFP_ATOMIC.
@@ -296,9 +296,12 @@ EXPORT_SYMBOL(build_skb);
296struct netdev_alloc_cache { 296struct netdev_alloc_cache {
297 struct page *page; 297 struct page *page;
298 unsigned int offset; 298 unsigned int offset;
299 unsigned int pagecnt_bias;
299}; 300};
300static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); 301static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache);
301 302
303#define NETDEV_PAGECNT_BIAS (PAGE_SIZE / SMP_CACHE_BYTES)
304
302/** 305/**
303 * netdev_alloc_frag - allocate a page fragment 306 * netdev_alloc_frag - allocate a page fragment
304 * @fragsz: fragment size 307 * @fragsz: fragment size
@@ -317,17 +320,26 @@ void *netdev_alloc_frag(unsigned int fragsz)
317 if (unlikely(!nc->page)) { 320 if (unlikely(!nc->page)) {
318refill: 321refill:
319 nc->page = alloc_page(GFP_ATOMIC | __GFP_COLD); 322 nc->page = alloc_page(GFP_ATOMIC | __GFP_COLD);
323 if (unlikely(!nc->page))
324 goto end;
325recycle:
326 atomic_set(&nc->page->_count, NETDEV_PAGECNT_BIAS);
327 nc->pagecnt_bias = NETDEV_PAGECNT_BIAS;
320 nc->offset = 0; 328 nc->offset = 0;
321 } 329 }
322 if (likely(nc->page)) { 330
323 if (nc->offset + fragsz > PAGE_SIZE) { 331 if (nc->offset + fragsz > PAGE_SIZE) {
324 put_page(nc->page); 332 /* avoid unnecessary locked operations if possible */
325 goto refill; 333 if ((atomic_read(&nc->page->_count) == nc->pagecnt_bias) ||
326 } 334 atomic_sub_and_test(nc->pagecnt_bias, &nc->page->_count))
327 data = page_address(nc->page) + nc->offset; 335 goto recycle;
328 nc->offset += fragsz; 336 goto refill;
329 get_page(nc->page);
330 } 337 }
338
339 data = page_address(nc->page) + nc->offset;
340 nc->offset += fragsz;
341 nc->pagecnt_bias--;
342end:
331 local_irq_restore(flags); 343 local_irq_restore(flags);
332 return data; 344 return data;
333} 345}
@@ -353,7 +365,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
353 unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + 365 unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) +
354 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); 366 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
355 367
356 if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) { 368 if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) {
357 void *data = netdev_alloc_frag(fragsz); 369 void *data = netdev_alloc_frag(fragsz);
358 370
359 if (likely(data)) { 371 if (likely(data)) {
@@ -713,7 +725,8 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)
713} 725}
714EXPORT_SYMBOL_GPL(skb_morph); 726EXPORT_SYMBOL_GPL(skb_morph);
715 727
716/* skb_copy_ubufs - copy userspace skb frags buffers to kernel 728/**
729 * skb_copy_ubufs - copy userspace skb frags buffers to kernel
717 * @skb: the skb to modify 730 * @skb: the skb to modify
718 * @gfp_mask: allocation priority 731 * @gfp_mask: allocation priority
719 * 732 *
@@ -738,7 +751,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
738 u8 *vaddr; 751 u8 *vaddr;
739 skb_frag_t *f = &skb_shinfo(skb)->frags[i]; 752 skb_frag_t *f = &skb_shinfo(skb)->frags[i];
740 753
741 page = alloc_page(GFP_ATOMIC); 754 page = alloc_page(gfp_mask);
742 if (!page) { 755 if (!page) {
743 while (head) { 756 while (head) {
744 struct page *next = (struct page *)head->private; 757 struct page *next = (struct page *)head->private;
@@ -756,22 +769,22 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
756 } 769 }
757 770
758 /* skb frags release userspace buffers */ 771 /* skb frags release userspace buffers */
759 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 772 for (i = 0; i < num_frags; i++)
760 skb_frag_unref(skb, i); 773 skb_frag_unref(skb, i);
761 774
762 uarg->callback(uarg); 775 uarg->callback(uarg);
763 776
764 /* skb frags point to kernel buffers */ 777 /* skb frags point to kernel buffers */
765 for (i = skb_shinfo(skb)->nr_frags; i > 0; i--) { 778 for (i = num_frags - 1; i >= 0; i--) {
766 __skb_fill_page_desc(skb, i-1, head, 0, 779 __skb_fill_page_desc(skb, i, head, 0,
767 skb_shinfo(skb)->frags[i - 1].size); 780 skb_shinfo(skb)->frags[i].size);
768 head = (struct page *)head->private; 781 head = (struct page *)head->private;
769 } 782 }
770 783
771 skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; 784 skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
772 return 0; 785 return 0;
773} 786}
774 787EXPORT_SYMBOL_GPL(skb_copy_ubufs);
775 788
776/** 789/**
777 * skb_clone - duplicate an sk_buff 790 * skb_clone - duplicate an sk_buff
@@ -791,10 +804,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
791{ 804{
792 struct sk_buff *n; 805 struct sk_buff *n;
793 806
794 if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { 807 if (skb_orphan_frags(skb, gfp_mask))
795 if (skb_copy_ubufs(skb, gfp_mask)) 808 return NULL;
796 return NULL;
797 }
798 809
799 n = skb + 1; 810 n = skb + 1;
800 if (skb->fclone == SKB_FCLONE_ORIG && 811 if (skb->fclone == SKB_FCLONE_ORIG &&
@@ -914,12 +925,10 @@ struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
914 if (skb_shinfo(skb)->nr_frags) { 925 if (skb_shinfo(skb)->nr_frags) {
915 int i; 926 int i;
916 927
917 if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { 928 if (skb_orphan_frags(skb, gfp_mask)) {
918 if (skb_copy_ubufs(skb, gfp_mask)) { 929 kfree_skb(n);
919 kfree_skb(n); 930 n = NULL;
920 n = NULL; 931 goto out;
921 goto out;
922 }
923 } 932 }
924 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 933 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
925 skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; 934 skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
@@ -992,10 +1001,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
992 */ 1001 */
993 if (skb_cloned(skb)) { 1002 if (skb_cloned(skb)) {
994 /* copy this zero copy skb frags */ 1003 /* copy this zero copy skb frags */
995 if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { 1004 if (skb_orphan_frags(skb, gfp_mask))
996 if (skb_copy_ubufs(skb, gfp_mask)) 1005 goto nofrags;
997 goto nofrags;
998 }
999 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 1006 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
1000 skb_frag_ref(skb, i); 1007 skb_frag_ref(skb, i);
1001 1008
@@ -2614,7 +2621,7 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
2614EXPORT_SYMBOL(skb_find_text); 2621EXPORT_SYMBOL(skb_find_text);
2615 2622
2616/** 2623/**
2617 * skb_append_datato_frags: - append the user data to a skb 2624 * skb_append_datato_frags - append the user data to a skb
2618 * @sk: sock structure 2625 * @sk: sock structure
2619 * @skb: skb structure to be appened with user data. 2626 * @skb: skb structure to be appened with user data.
2620 * @getfrag: call back function to be used for getting the user data 2627 * @getfrag: call back function to be used for getting the user data