diff options
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r-- | net/core/skbuff.c | 92 |
1 files changed, 44 insertions, 48 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c83b421341c..752c1972b3a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -202,8 +202,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
202 | skb->data = data; | 202 | skb->data = data; |
203 | skb_reset_tail_pointer(skb); | 203 | skb_reset_tail_pointer(skb); |
204 | skb->end = skb->tail + size; | 204 | skb->end = skb->tail + size; |
205 | kmemcheck_annotate_bitfield(skb, flags1); | ||
206 | kmemcheck_annotate_bitfield(skb, flags2); | ||
207 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 205 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
208 | skb->mac_header = ~0U; | 206 | skb->mac_header = ~0U; |
209 | #endif | 207 | #endif |
@@ -340,7 +338,7 @@ static void skb_release_data(struct sk_buff *skb) | |||
340 | put_page(skb_shinfo(skb)->frags[i].page); | 338 | put_page(skb_shinfo(skb)->frags[i].page); |
341 | } | 339 | } |
342 | 340 | ||
343 | if (skb_has_frags(skb)) | 341 | if (skb_has_frag_list(skb)) |
344 | skb_drop_fraglist(skb); | 342 | skb_drop_fraglist(skb); |
345 | 343 | ||
346 | kfree(skb->head); | 344 | kfree(skb->head); |
@@ -685,16 +683,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
685 | 683 | ||
686 | struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) | 684 | struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) |
687 | { | 685 | { |
688 | int headerlen = skb->data - skb->head; | 686 | int headerlen = skb_headroom(skb); |
689 | /* | 687 | unsigned int size = (skb_end_pointer(skb) - skb->head) + skb->data_len; |
690 | * Allocate the copy buffer | 688 | struct sk_buff *n = alloc_skb(size, gfp_mask); |
691 | */ | 689 | |
692 | struct sk_buff *n; | ||
693 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
694 | n = alloc_skb(skb->end + skb->data_len, gfp_mask); | ||
695 | #else | ||
696 | n = alloc_skb(skb->end - skb->head + skb->data_len, gfp_mask); | ||
697 | #endif | ||
698 | if (!n) | 690 | if (!n) |
699 | return NULL; | 691 | return NULL; |
700 | 692 | ||
@@ -726,20 +718,14 @@ EXPORT_SYMBOL(skb_copy); | |||
726 | 718 | ||
727 | struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) | 719 | struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) |
728 | { | 720 | { |
729 | /* | 721 | unsigned int size = skb_end_pointer(skb) - skb->head; |
730 | * Allocate the copy buffer | 722 | struct sk_buff *n = alloc_skb(size, gfp_mask); |
731 | */ | 723 | |
732 | struct sk_buff *n; | ||
733 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
734 | n = alloc_skb(skb->end, gfp_mask); | ||
735 | #else | ||
736 | n = alloc_skb(skb->end - skb->head, gfp_mask); | ||
737 | #endif | ||
738 | if (!n) | 724 | if (!n) |
739 | goto out; | 725 | goto out; |
740 | 726 | ||
741 | /* Set the data pointer */ | 727 | /* Set the data pointer */ |
742 | skb_reserve(n, skb->data - skb->head); | 728 | skb_reserve(n, skb_headroom(skb)); |
743 | /* Set the tail pointer and length */ | 729 | /* Set the tail pointer and length */ |
744 | skb_put(n, skb_headlen(skb)); | 730 | skb_put(n, skb_headlen(skb)); |
745 | /* Copy the bytes */ | 731 | /* Copy the bytes */ |
@@ -759,7 +745,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) | |||
759 | skb_shinfo(n)->nr_frags = i; | 745 | skb_shinfo(n)->nr_frags = i; |
760 | } | 746 | } |
761 | 747 | ||
762 | if (skb_has_frags(skb)) { | 748 | if (skb_has_frag_list(skb)) { |
763 | skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; | 749 | skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; |
764 | skb_clone_fraglist(n); | 750 | skb_clone_fraglist(n); |
765 | } | 751 | } |
@@ -791,12 +777,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
791 | { | 777 | { |
792 | int i; | 778 | int i; |
793 | u8 *data; | 779 | u8 *data; |
794 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 780 | int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail; |
795 | int size = nhead + skb->end + ntail; | ||
796 | #else | ||
797 | int size = nhead + (skb->end - skb->head) + ntail; | ||
798 | #endif | ||
799 | long off; | 781 | long off; |
782 | bool fastpath; | ||
800 | 783 | ||
801 | BUG_ON(nhead < 0); | 784 | BUG_ON(nhead < 0); |
802 | 785 | ||
@@ -810,23 +793,36 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
810 | goto nodata; | 793 | goto nodata; |
811 | 794 | ||
812 | /* Copy only real data... and, alas, header. This should be | 795 | /* Copy only real data... and, alas, header. This should be |
813 | * optimized for the cases when header is void. */ | 796 | * optimized for the cases when header is void. |
814 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 797 | */ |
815 | memcpy(data + nhead, skb->head, skb->tail); | 798 | memcpy(data + nhead, skb->head, skb_tail_pointer(skb) - skb->head); |
816 | #else | 799 | |
817 | memcpy(data + nhead, skb->head, skb->tail - skb->head); | 800 | memcpy((struct skb_shared_info *)(data + size), |
818 | #endif | 801 | skb_shinfo(skb), |
819 | memcpy(data + size, skb_end_pointer(skb), | ||
820 | offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); | 802 | offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); |
821 | 803 | ||
822 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 804 | /* Check if we can avoid taking references on fragments if we own |
823 | get_page(skb_shinfo(skb)->frags[i].page); | 805 | * the last reference on skb->head. (see skb_release_data()) |
806 | */ | ||
807 | if (!skb->cloned) | ||
808 | fastpath = true; | ||
809 | else { | ||
810 | int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; | ||
824 | 811 | ||
825 | if (skb_has_frags(skb)) | 812 | fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; |
826 | skb_clone_fraglist(skb); | 813 | } |
827 | 814 | ||
828 | skb_release_data(skb); | 815 | if (fastpath) { |
816 | kfree(skb->head); | ||
817 | } else { | ||
818 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
819 | get_page(skb_shinfo(skb)->frags[i].page); | ||
829 | 820 | ||
821 | if (skb_has_frag_list(skb)) | ||
822 | skb_clone_fraglist(skb); | ||
823 | |||
824 | skb_release_data(skb); | ||
825 | } | ||
830 | off = (data + nhead) - skb->head; | 826 | off = (data + nhead) - skb->head; |
831 | 827 | ||
832 | skb->head = data; | 828 | skb->head = data; |
@@ -1099,7 +1095,7 @@ drop_pages: | |||
1099 | for (; i < nfrags; i++) | 1095 | for (; i < nfrags; i++) |
1100 | put_page(skb_shinfo(skb)->frags[i].page); | 1096 | put_page(skb_shinfo(skb)->frags[i].page); |
1101 | 1097 | ||
1102 | if (skb_has_frags(skb)) | 1098 | if (skb_has_frag_list(skb)) |
1103 | skb_drop_fraglist(skb); | 1099 | skb_drop_fraglist(skb); |
1104 | goto done; | 1100 | goto done; |
1105 | } | 1101 | } |
@@ -1194,7 +1190,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) | |||
1194 | /* Optimization: no fragments, no reasons to preestimate | 1190 | /* Optimization: no fragments, no reasons to preestimate |
1195 | * size of pulled pages. Superb. | 1191 | * size of pulled pages. Superb. |
1196 | */ | 1192 | */ |
1197 | if (!skb_has_frags(skb)) | 1193 | if (!skb_has_frag_list(skb)) |
1198 | goto pull_pages; | 1194 | goto pull_pages; |
1199 | 1195 | ||
1200 | /* Estimate size of pulled pages. */ | 1196 | /* Estimate size of pulled pages. */ |
@@ -2323,7 +2319,7 @@ next_skb: | |||
2323 | st->frag_data = NULL; | 2319 | st->frag_data = NULL; |
2324 | } | 2320 | } |
2325 | 2321 | ||
2326 | if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { | 2322 | if (st->root_skb == st->cur_skb && skb_has_frag_list(st->root_skb)) { |
2327 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; | 2323 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; |
2328 | st->frag_idx = 0; | 2324 | st->frag_idx = 0; |
2329 | goto next_skb; | 2325 | goto next_skb; |
@@ -2893,7 +2889,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2893 | return -ENOMEM; | 2889 | return -ENOMEM; |
2894 | 2890 | ||
2895 | /* Easy case. Most of packets will go this way. */ | 2891 | /* Easy case. Most of packets will go this way. */ |
2896 | if (!skb_has_frags(skb)) { | 2892 | if (!skb_has_frag_list(skb)) { |
2897 | /* A little of trouble, not enough of space for trailer. | 2893 | /* A little of trouble, not enough of space for trailer. |
2898 | * This should not happen, when stack is tuned to generate | 2894 | * This should not happen, when stack is tuned to generate |
2899 | * good frames. OK, on miss we reallocate and reserve even more | 2895 | * good frames. OK, on miss we reallocate and reserve even more |
@@ -2928,7 +2924,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2928 | 2924 | ||
2929 | if (skb1->next == NULL && tailbits) { | 2925 | if (skb1->next == NULL && tailbits) { |
2930 | if (skb_shinfo(skb1)->nr_frags || | 2926 | if (skb_shinfo(skb1)->nr_frags || |
2931 | skb_has_frags(skb1) || | 2927 | skb_has_frag_list(skb1) || |
2932 | skb_tailroom(skb1) < tailbits) | 2928 | skb_tailroom(skb1) < tailbits) |
2933 | ntail = tailbits + 128; | 2929 | ntail = tailbits + 128; |
2934 | } | 2930 | } |
@@ -2937,7 +2933,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2937 | skb_cloned(skb1) || | 2933 | skb_cloned(skb1) || |
2938 | ntail || | 2934 | ntail || |
2939 | skb_shinfo(skb1)->nr_frags || | 2935 | skb_shinfo(skb1)->nr_frags || |
2940 | skb_has_frags(skb1)) { | 2936 | skb_has_frag_list(skb1)) { |
2941 | struct sk_buff *skb2; | 2937 | struct sk_buff *skb2; |
2942 | 2938 | ||
2943 | /* Fuck, we are miserable poor guys... */ | 2939 | /* Fuck, we are miserable poor guys... */ |
@@ -3020,7 +3016,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3020 | } else { | 3016 | } else { |
3021 | /* | 3017 | /* |
3022 | * no hardware time stamps available, | 3018 | * no hardware time stamps available, |
3023 | * so keep the skb_shared_tx and only | 3019 | * so keep the shared tx_flags and only |
3024 | * store software time stamp | 3020 | * store software time stamp |
3025 | */ | 3021 | */ |
3026 | skb->tstamp = ktime_get_real(); | 3022 | skb->tstamp = ktime_get_real(); |