diff options
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r-- | net/core/skbuff.c | 157 |
1 files changed, 62 insertions, 95 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3ab989b0de42..33245ef54c3b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -104,47 +104,37 @@ static const struct pipe_buf_operations sock_pipe_buf_ops = { | |||
104 | .get = sock_pipe_buf_get, | 104 | .get = sock_pipe_buf_get, |
105 | }; | 105 | }; |
106 | 106 | ||
107 | /* | ||
108 | * Keep out-of-line to prevent kernel bloat. | ||
109 | * __builtin_return_address is not used because it is not always | ||
110 | * reliable. | ||
111 | */ | ||
112 | |||
113 | /** | 107 | /** |
114 | * skb_over_panic - private function | 108 | * skb_panic - private function for out-of-line support |
115 | * @skb: buffer | 109 | * @skb: buffer |
116 | * @sz: size | 110 | * @sz: size |
117 | * @here: address | 111 | * @addr: address |
118 | * | 112 | * @msg: skb_over_panic or skb_under_panic |
119 | * Out of line support code for skb_put(). Not user callable. | 113 | * |
114 | * Out-of-line support for skb_put() and skb_push(). | ||
115 | * Called via the wrapper skb_over_panic() or skb_under_panic(). | ||
116 | * Keep out of line to prevent kernel bloat. | ||
117 | * __builtin_return_address is not used because it is not always reliable. | ||
120 | */ | 118 | */ |
121 | static void skb_over_panic(struct sk_buff *skb, int sz, void *here) | 119 | static void skb_panic(struct sk_buff *skb, unsigned int sz, void *addr, |
120 | const char msg[]) | ||
122 | { | 121 | { |
123 | pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", | 122 | pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", |
124 | __func__, here, skb->len, sz, skb->head, skb->data, | 123 | msg, addr, skb->len, sz, skb->head, skb->data, |
125 | (unsigned long)skb->tail, (unsigned long)skb->end, | 124 | (unsigned long)skb->tail, (unsigned long)skb->end, |
126 | skb->dev ? skb->dev->name : "<NULL>"); | 125 | skb->dev ? skb->dev->name : "<NULL>"); |
127 | BUG(); | 126 | BUG(); |
128 | } | 127 | } |
129 | 128 | ||
130 | /** | 129 | static void skb_over_panic(struct sk_buff *skb, unsigned int sz, void *addr) |
131 | * skb_under_panic - private function | ||
132 | * @skb: buffer | ||
133 | * @sz: size | ||
134 | * @here: address | ||
135 | * | ||
136 | * Out of line support code for skb_push(). Not user callable. | ||
137 | */ | ||
138 | |||
139 | static void skb_under_panic(struct sk_buff *skb, int sz, void *here) | ||
140 | { | 130 | { |
141 | pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", | 131 | skb_panic(skb, sz, addr, __func__); |
142 | __func__, here, skb->len, sz, skb->head, skb->data, | ||
143 | (unsigned long)skb->tail, (unsigned long)skb->end, | ||
144 | skb->dev ? skb->dev->name : "<NULL>"); | ||
145 | BUG(); | ||
146 | } | 132 | } |
147 | 133 | ||
134 | static void skb_under_panic(struct sk_buff *skb, unsigned int sz, void *addr) | ||
135 | { | ||
136 | skb_panic(skb, sz, addr, __func__); | ||
137 | } | ||
148 | 138 | ||
149 | /* | 139 | /* |
150 | * kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tells | 140 | * kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tells |
@@ -155,8 +145,9 @@ static void skb_under_panic(struct sk_buff *skb, int sz, void *here) | |||
155 | */ | 145 | */ |
156 | #define kmalloc_reserve(size, gfp, node, pfmemalloc) \ | 146 | #define kmalloc_reserve(size, gfp, node, pfmemalloc) \ |
157 | __kmalloc_reserve(size, gfp, node, _RET_IP_, pfmemalloc) | 147 | __kmalloc_reserve(size, gfp, node, _RET_IP_, pfmemalloc) |
158 | void *__kmalloc_reserve(size_t size, gfp_t flags, int node, unsigned long ip, | 148 | |
159 | bool *pfmemalloc) | 149 | static void *__kmalloc_reserve(size_t size, gfp_t flags, int node, |
150 | unsigned long ip, bool *pfmemalloc) | ||
160 | { | 151 | { |
161 | void *obj; | 152 | void *obj; |
162 | bool ret_pfmemalloc = false; | 153 | bool ret_pfmemalloc = false; |
@@ -259,6 +250,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
259 | skb->end = skb->tail + size; | 250 | skb->end = skb->tail + size; |
260 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 251 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
261 | skb->mac_header = ~0U; | 252 | skb->mac_header = ~0U; |
253 | skb->transport_header = ~0U; | ||
262 | #endif | 254 | #endif |
263 | 255 | ||
264 | /* make sure we initialize shinfo sequentially */ | 256 | /* make sure we initialize shinfo sequentially */ |
@@ -327,6 +319,7 @@ struct sk_buff *build_skb(void *data, unsigned int frag_size) | |||
327 | skb->end = skb->tail + size; | 319 | skb->end = skb->tail + size; |
328 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 320 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
329 | skb->mac_header = ~0U; | 321 | skb->mac_header = ~0U; |
322 | skb->transport_header = ~0U; | ||
330 | #endif | 323 | #endif |
331 | 324 | ||
332 | /* make sure we initialize shinfo sequentially */ | 325 | /* make sure we initialize shinfo sequentially */ |
@@ -348,10 +341,6 @@ struct netdev_alloc_cache { | |||
348 | }; | 341 | }; |
349 | static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); | 342 | static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); |
350 | 343 | ||
351 | #define NETDEV_FRAG_PAGE_MAX_ORDER get_order(32768) | ||
352 | #define NETDEV_FRAG_PAGE_MAX_SIZE (PAGE_SIZE << NETDEV_FRAG_PAGE_MAX_ORDER) | ||
353 | #define NETDEV_PAGECNT_MAX_BIAS NETDEV_FRAG_PAGE_MAX_SIZE | ||
354 | |||
355 | static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) | 344 | static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) |
356 | { | 345 | { |
357 | struct netdev_alloc_cache *nc; | 346 | struct netdev_alloc_cache *nc; |
@@ -683,7 +672,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
683 | new->network_header = old->network_header; | 672 | new->network_header = old->network_header; |
684 | new->mac_header = old->mac_header; | 673 | new->mac_header = old->mac_header; |
685 | new->inner_transport_header = old->inner_transport_header; | 674 | new->inner_transport_header = old->inner_transport_header; |
686 | new->inner_network_header = old->inner_transport_header; | 675 | new->inner_network_header = old->inner_network_header; |
687 | skb_dst_copy(new, old); | 676 | skb_dst_copy(new, old); |
688 | new->rxhash = old->rxhash; | 677 | new->rxhash = old->rxhash; |
689 | new->ooo_okay = old->ooo_okay; | 678 | new->ooo_okay = old->ooo_okay; |
@@ -1649,7 +1638,7 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) | |||
1649 | 1638 | ||
1650 | static struct page *linear_to_page(struct page *page, unsigned int *len, | 1639 | static struct page *linear_to_page(struct page *page, unsigned int *len, |
1651 | unsigned int *offset, | 1640 | unsigned int *offset, |
1652 | struct sk_buff *skb, struct sock *sk) | 1641 | struct sock *sk) |
1653 | { | 1642 | { |
1654 | struct page_frag *pfrag = sk_page_frag(sk); | 1643 | struct page_frag *pfrag = sk_page_frag(sk); |
1655 | 1644 | ||
@@ -1682,14 +1671,14 @@ static bool spd_can_coalesce(const struct splice_pipe_desc *spd, | |||
1682 | static bool spd_fill_page(struct splice_pipe_desc *spd, | 1671 | static bool spd_fill_page(struct splice_pipe_desc *spd, |
1683 | struct pipe_inode_info *pipe, struct page *page, | 1672 | struct pipe_inode_info *pipe, struct page *page, |
1684 | unsigned int *len, unsigned int offset, | 1673 | unsigned int *len, unsigned int offset, |
1685 | struct sk_buff *skb, bool linear, | 1674 | bool linear, |
1686 | struct sock *sk) | 1675 | struct sock *sk) |
1687 | { | 1676 | { |
1688 | if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) | 1677 | if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) |
1689 | return true; | 1678 | return true; |
1690 | 1679 | ||
1691 | if (linear) { | 1680 | if (linear) { |
1692 | page = linear_to_page(page, len, &offset, skb, sk); | 1681 | page = linear_to_page(page, len, &offset, sk); |
1693 | if (!page) | 1682 | if (!page) |
1694 | return true; | 1683 | return true; |
1695 | } | 1684 | } |
@@ -1706,23 +1695,9 @@ static bool spd_fill_page(struct splice_pipe_desc *spd, | |||
1706 | return false; | 1695 | return false; |
1707 | } | 1696 | } |
1708 | 1697 | ||
1709 | static inline void __segment_seek(struct page **page, unsigned int *poff, | ||
1710 | unsigned int *plen, unsigned int off) | ||
1711 | { | ||
1712 | unsigned long n; | ||
1713 | |||
1714 | *poff += off; | ||
1715 | n = *poff / PAGE_SIZE; | ||
1716 | if (n) | ||
1717 | *page = nth_page(*page, n); | ||
1718 | |||
1719 | *poff = *poff % PAGE_SIZE; | ||
1720 | *plen -= off; | ||
1721 | } | ||
1722 | |||
1723 | static bool __splice_segment(struct page *page, unsigned int poff, | 1698 | static bool __splice_segment(struct page *page, unsigned int poff, |
1724 | unsigned int plen, unsigned int *off, | 1699 | unsigned int plen, unsigned int *off, |
1725 | unsigned int *len, struct sk_buff *skb, | 1700 | unsigned int *len, |
1726 | struct splice_pipe_desc *spd, bool linear, | 1701 | struct splice_pipe_desc *spd, bool linear, |
1727 | struct sock *sk, | 1702 | struct sock *sk, |
1728 | struct pipe_inode_info *pipe) | 1703 | struct pipe_inode_info *pipe) |
@@ -1737,23 +1712,19 @@ static bool __splice_segment(struct page *page, unsigned int poff, | |||
1737 | } | 1712 | } |
1738 | 1713 | ||
1739 | /* ignore any bits we already processed */ | 1714 | /* ignore any bits we already processed */ |
1740 | if (*off) { | 1715 | poff += *off; |
1741 | __segment_seek(&page, &poff, &plen, *off); | 1716 | plen -= *off; |
1742 | *off = 0; | 1717 | *off = 0; |
1743 | } | ||
1744 | 1718 | ||
1745 | do { | 1719 | do { |
1746 | unsigned int flen = min(*len, plen); | 1720 | unsigned int flen = min(*len, plen); |
1747 | 1721 | ||
1748 | /* the linear region may spread across several pages */ | 1722 | if (spd_fill_page(spd, pipe, page, &flen, poff, |
1749 | flen = min_t(unsigned int, flen, PAGE_SIZE - poff); | 1723 | linear, sk)) |
1750 | |||
1751 | if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk)) | ||
1752 | return true; | 1724 | return true; |
1753 | 1725 | poff += flen; | |
1754 | __segment_seek(&page, &poff, &plen, flen); | 1726 | plen -= flen; |
1755 | *len -= flen; | 1727 | *len -= flen; |
1756 | |||
1757 | } while (*len && plen); | 1728 | } while (*len && plen); |
1758 | 1729 | ||
1759 | return false; | 1730 | return false; |
@@ -1777,7 +1748,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, | |||
1777 | if (__splice_segment(virt_to_page(skb->data), | 1748 | if (__splice_segment(virt_to_page(skb->data), |
1778 | (unsigned long) skb->data & (PAGE_SIZE - 1), | 1749 | (unsigned long) skb->data & (PAGE_SIZE - 1), |
1779 | skb_headlen(skb), | 1750 | skb_headlen(skb), |
1780 | offset, len, skb, spd, | 1751 | offset, len, spd, |
1781 | skb_head_is_locked(skb), | 1752 | skb_head_is_locked(skb), |
1782 | sk, pipe)) | 1753 | sk, pipe)) |
1783 | return true; | 1754 | return true; |
@@ -1790,7 +1761,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, | |||
1790 | 1761 | ||
1791 | if (__splice_segment(skb_frag_page(f), | 1762 | if (__splice_segment(skb_frag_page(f), |
1792 | f->page_offset, skb_frag_size(f), | 1763 | f->page_offset, skb_frag_size(f), |
1793 | offset, len, skb, spd, false, sk, pipe)) | 1764 | offset, len, spd, false, sk, pipe)) |
1794 | return true; | 1765 | return true; |
1795 | } | 1766 | } |
1796 | 1767 | ||
@@ -2355,6 +2326,7 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len) | |||
2355 | { | 2326 | { |
2356 | int pos = skb_headlen(skb); | 2327 | int pos = skb_headlen(skb); |
2357 | 2328 | ||
2329 | skb_shinfo(skb1)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; | ||
2358 | if (len < pos) /* Split line is inside header. */ | 2330 | if (len < pos) /* Split line is inside header. */ |
2359 | skb_split_inside_header(skb, skb1, len, pos); | 2331 | skb_split_inside_header(skb, skb1, len, pos); |
2360 | else /* Second chunk has no header, nothing to copy. */ | 2332 | else /* Second chunk has no header, nothing to copy. */ |
@@ -2686,48 +2658,37 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, | |||
2686 | int len, int odd, struct sk_buff *skb), | 2658 | int len, int odd, struct sk_buff *skb), |
2687 | void *from, int length) | 2659 | void *from, int length) |
2688 | { | 2660 | { |
2689 | int frg_cnt = 0; | 2661 | int frg_cnt = skb_shinfo(skb)->nr_frags; |
2690 | skb_frag_t *frag = NULL; | 2662 | int copy; |
2691 | struct page *page = NULL; | ||
2692 | int copy, left; | ||
2693 | int offset = 0; | 2663 | int offset = 0; |
2694 | int ret; | 2664 | int ret; |
2665 | struct page_frag *pfrag = ¤t->task_frag; | ||
2695 | 2666 | ||
2696 | do { | 2667 | do { |
2697 | /* Return error if we don't have space for new frag */ | 2668 | /* Return error if we don't have space for new frag */ |
2698 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
2699 | if (frg_cnt >= MAX_SKB_FRAGS) | 2669 | if (frg_cnt >= MAX_SKB_FRAGS) |
2700 | return -EFAULT; | 2670 | return -EMSGSIZE; |
2701 | 2671 | ||
2702 | /* allocate a new page for next frag */ | 2672 | if (!sk_page_frag_refill(sk, pfrag)) |
2703 | page = alloc_pages(sk->sk_allocation, 0); | ||
2704 | |||
2705 | /* If alloc_page fails just return failure and caller will | ||
2706 | * free previous allocated pages by doing kfree_skb() | ||
2707 | */ | ||
2708 | if (page == NULL) | ||
2709 | return -ENOMEM; | 2673 | return -ENOMEM; |
2710 | 2674 | ||
2711 | /* initialize the next frag */ | ||
2712 | skb_fill_page_desc(skb, frg_cnt, page, 0, 0); | ||
2713 | skb->truesize += PAGE_SIZE; | ||
2714 | atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc); | ||
2715 | |||
2716 | /* get the new initialized frag */ | ||
2717 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
2718 | frag = &skb_shinfo(skb)->frags[frg_cnt - 1]; | ||
2719 | |||
2720 | /* copy the user data to page */ | 2675 | /* copy the user data to page */ |
2721 | left = PAGE_SIZE - frag->page_offset; | 2676 | copy = min_t(int, length, pfrag->size - pfrag->offset); |
2722 | copy = (length > left)? left : length; | ||
2723 | 2677 | ||
2724 | ret = getfrag(from, skb_frag_address(frag) + skb_frag_size(frag), | 2678 | ret = getfrag(from, page_address(pfrag->page) + pfrag->offset, |
2725 | offset, copy, 0, skb); | 2679 | offset, copy, 0, skb); |
2726 | if (ret < 0) | 2680 | if (ret < 0) |
2727 | return -EFAULT; | 2681 | return -EFAULT; |
2728 | 2682 | ||
2729 | /* copy was successful so update the size parameters */ | 2683 | /* copy was successful so update the size parameters */ |
2730 | skb_frag_size_add(frag, copy); | 2684 | skb_fill_page_desc(skb, frg_cnt, pfrag->page, pfrag->offset, |
2685 | copy); | ||
2686 | frg_cnt++; | ||
2687 | pfrag->offset += copy; | ||
2688 | get_page(pfrag->page); | ||
2689 | |||
2690 | skb->truesize += copy; | ||
2691 | atomic_add(copy, &sk->sk_wmem_alloc); | ||
2731 | skb->len += copy; | 2692 | skb->len += copy; |
2732 | skb->data_len += copy; | 2693 | skb->data_len += copy; |
2733 | offset += copy; | 2694 | offset += copy; |
@@ -2777,6 +2738,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
2777 | unsigned int mss = skb_shinfo(skb)->gso_size; | 2738 | unsigned int mss = skb_shinfo(skb)->gso_size; |
2778 | unsigned int doffset = skb->data - skb_mac_header(skb); | 2739 | unsigned int doffset = skb->data - skb_mac_header(skb); |
2779 | unsigned int offset = doffset; | 2740 | unsigned int offset = doffset; |
2741 | unsigned int tnl_hlen = skb_tnl_header_len(skb); | ||
2780 | unsigned int headroom; | 2742 | unsigned int headroom; |
2781 | unsigned int len; | 2743 | unsigned int len; |
2782 | int sg = !!(features & NETIF_F_SG); | 2744 | int sg = !!(features & NETIF_F_SG); |
@@ -2853,7 +2815,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
2853 | skb_set_network_header(nskb, skb->mac_len); | 2815 | skb_set_network_header(nskb, skb->mac_len); |
2854 | nskb->transport_header = (nskb->network_header + | 2816 | nskb->transport_header = (nskb->network_header + |
2855 | skb_network_header_len(skb)); | 2817 | skb_network_header_len(skb)); |
2856 | skb_copy_from_linear_data(skb, nskb->data, doffset); | 2818 | |
2819 | skb_copy_from_linear_data_offset(skb, -tnl_hlen, | ||
2820 | nskb->data - tnl_hlen, | ||
2821 | doffset + tnl_hlen); | ||
2857 | 2822 | ||
2858 | if (fskb != skb_shinfo(skb)->frag_list) | 2823 | if (fskb != skb_shinfo(skb)->frag_list) |
2859 | continue; | 2824 | continue; |
@@ -2871,6 +2836,8 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
2871 | skb_copy_from_linear_data_offset(skb, offset, | 2836 | skb_copy_from_linear_data_offset(skb, offset, |
2872 | skb_put(nskb, hsize), hsize); | 2837 | skb_put(nskb, hsize), hsize); |
2873 | 2838 | ||
2839 | skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; | ||
2840 | |||
2874 | while (pos < offset + len && i < nfrags) { | 2841 | while (pos < offset + len && i < nfrags) { |
2875 | *frag = skb_shinfo(skb)->frags[i]; | 2842 | *frag = skb_shinfo(skb)->frags[i]; |
2876 | __skb_frag_ref(frag); | 2843 | __skb_frag_ref(frag); |