aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Campbell <Ian.Campbell@citrix.com>2011-08-22 19:44:58 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-24 20:52:11 -0400
commitea2ab69379a941c6f8884e290fdd28c93936a778 (patch)
treec02aa9c5ed66b1640b54bb6b763d131b9419be29
parent15133fbbb91ae695f153fb48daa6a1a8af4a5032 (diff)
net: convert core to skb paged frag APIs
Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: "Michał Mirosław" <mirq-linux@rere.qmqm.pl> Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/skbuff.h4
-rw-r--r--net/core/datagram.c8
-rw-r--r--net/core/dev.c16
-rw-r--r--net/core/kmap_skb.h2
-rw-r--r--net/core/pktgen.c3
-rw-r--r--net/core/skbuff.c29
-rw-r--r--net/core/sock.c12
-rw-r--r--net/core/user_dma.c2
8 files changed, 38 insertions, 38 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7b0e1773f9cd..8d426281259d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1898,12 +1898,12 @@ static inline int skb_add_data(struct sk_buff *skb,
1898} 1898}
1899 1899
1900static inline int skb_can_coalesce(struct sk_buff *skb, int i, 1900static inline int skb_can_coalesce(struct sk_buff *skb, int i,
1901 struct page *page, int off) 1901 const struct page *page, int off)
1902{ 1902{
1903 if (i) { 1903 if (i) {
1904 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; 1904 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1];
1905 1905
1906 return page == frag->page && 1906 return page == skb_frag_page(frag) &&
1907 off == frag->page_offset + frag->size; 1907 off == frag->page_offset + frag->size;
1908 } 1908 }
1909 return 0; 1909 return 0;
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 18ac112ea7ae..6449bed457d4 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -332,7 +332,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
332 int err; 332 int err;
333 u8 *vaddr; 333 u8 *vaddr;
334 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 334 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
335 struct page *page = frag->page; 335 struct page *page = skb_frag_page(frag);
336 336
337 if (copy > len) 337 if (copy > len)
338 copy = len; 338 copy = len;
@@ -418,7 +418,7 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
418 int err; 418 int err;
419 u8 *vaddr; 419 u8 *vaddr;
420 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 420 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
421 struct page *page = frag->page; 421 struct page *page = skb_frag_page(frag);
422 422
423 if (copy > len) 423 if (copy > len)
424 copy = len; 424 copy = len;
@@ -508,7 +508,7 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
508 int err; 508 int err;
509 u8 *vaddr; 509 u8 *vaddr;
510 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 510 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
511 struct page *page = frag->page; 511 struct page *page = skb_frag_page(frag);
512 512
513 if (copy > len) 513 if (copy > len)
514 copy = len; 514 copy = len;
@@ -594,7 +594,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
594 int err = 0; 594 int err = 0;
595 u8 *vaddr; 595 u8 *vaddr;
596 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 596 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
597 struct page *page = frag->page; 597 struct page *page = skb_frag_page(frag);
598 598
599 if (copy > len) 599 if (copy > len)
600 copy = len; 600 copy = len;
diff --git a/net/core/dev.c b/net/core/dev.c
index b668a3d9a189..b2e262ed3963 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1949,9 +1949,11 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
1949#ifdef CONFIG_HIGHMEM 1949#ifdef CONFIG_HIGHMEM
1950 int i; 1950 int i;
1951 if (!(dev->features & NETIF_F_HIGHDMA)) { 1951 if (!(dev->features & NETIF_F_HIGHDMA)) {
1952 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 1952 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1953 if (PageHighMem(skb_shinfo(skb)->frags[i].page)) 1953 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1954 if (PageHighMem(skb_frag_page(frag)))
1954 return 1; 1955 return 1;
1956 }
1955 } 1957 }
1956 1958
1957 if (PCI_DMA_BUS_IS_PHYS) { 1959 if (PCI_DMA_BUS_IS_PHYS) {
@@ -1960,7 +1962,8 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
1960 if (!pdev) 1962 if (!pdev)
1961 return 0; 1963 return 0;
1962 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1964 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1963 dma_addr_t addr = page_to_phys(skb_shinfo(skb)->frags[i].page); 1965 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1966 dma_addr_t addr = page_to_phys(skb_frag_page(frag));
1964 if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask) 1967 if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
1965 return 1; 1968 return 1;
1966 } 1969 }
@@ -3474,7 +3477,7 @@ pull:
3474 skb_shinfo(skb)->frags[0].size -= grow; 3477 skb_shinfo(skb)->frags[0].size -= grow;
3475 3478
3476 if (unlikely(!skb_shinfo(skb)->frags[0].size)) { 3479 if (unlikely(!skb_shinfo(skb)->frags[0].size)) {
3477 put_page(skb_shinfo(skb)->frags[0].page); 3480 skb_frag_unref(skb, 0);
3478 memmove(skb_shinfo(skb)->frags, 3481 memmove(skb_shinfo(skb)->frags,
3479 skb_shinfo(skb)->frags + 1, 3482 skb_shinfo(skb)->frags + 1,
3480 --skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t)); 3483 --skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
@@ -3538,10 +3541,9 @@ void skb_gro_reset_offset(struct sk_buff *skb)
3538 NAPI_GRO_CB(skb)->frag0_len = 0; 3541 NAPI_GRO_CB(skb)->frag0_len = 0;
3539 3542
3540 if (skb->mac_header == skb->tail && 3543 if (skb->mac_header == skb->tail &&
3541 !PageHighMem(skb_shinfo(skb)->frags[0].page)) { 3544 !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) {
3542 NAPI_GRO_CB(skb)->frag0 = 3545 NAPI_GRO_CB(skb)->frag0 =
3543 page_address(skb_shinfo(skb)->frags[0].page) + 3546 skb_frag_address(&skb_shinfo(skb)->frags[0]);
3544 skb_shinfo(skb)->frags[0].page_offset;
3545 NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size; 3547 NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size;
3546 } 3548 }
3547} 3549}
diff --git a/net/core/kmap_skb.h b/net/core/kmap_skb.h
index 283c2b993fb8..81e1ed7c8383 100644
--- a/net/core/kmap_skb.h
+++ b/net/core/kmap_skb.h
@@ -7,7 +7,7 @@ static inline void *kmap_skb_frag(const skb_frag_t *frag)
7 7
8 local_bh_disable(); 8 local_bh_disable();
9#endif 9#endif
10 return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ); 10 return kmap_atomic(skb_frag_page(frag), KM_SKB_DATA_SOFTIRQ);
11} 11}
12 12
13static inline void kunmap_skb_frag(void *vaddr) 13static inline void kunmap_skb_frag(void *vaddr)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index e35a6fbb8110..796044ac0bf3 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2602,8 +2602,7 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
2602 if (!pkt_dev->page) 2602 if (!pkt_dev->page)
2603 break; 2603 break;
2604 } 2604 }
2605 skb_shinfo(skb)->frags[i].page = pkt_dev->page; 2605 skb_frag_set_page(skb, i, pkt_dev->page);
2606 get_page(pkt_dev->page);
2607 skb_shinfo(skb)->frags[i].page_offset = 0; 2606 skb_shinfo(skb)->frags[i].page_offset = 0;
2608 /*last fragment, fill rest of data*/ 2607 /*last fragment, fill rest of data*/
2609 if (i == (frags - 1)) 2608 if (i == (frags - 1))
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e27334ec367a..296afd0aa8d2 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -326,7 +326,7 @@ static void skb_release_data(struct sk_buff *skb)
326 if (skb_shinfo(skb)->nr_frags) { 326 if (skb_shinfo(skb)->nr_frags) {
327 int i; 327 int i;
328 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 328 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
329 put_page(skb_shinfo(skb)->frags[i].page); 329 skb_frag_unref(skb, i);
330 } 330 }
331 331
332 /* 332 /*
@@ -809,7 +809,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
809 } 809 }
810 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 810 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
811 skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; 811 skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
812 get_page(skb_shinfo(n)->frags[i].page); 812 skb_frag_ref(skb, i);
813 } 813 }
814 skb_shinfo(n)->nr_frags = i; 814 skb_shinfo(n)->nr_frags = i;
815 } 815 }
@@ -901,7 +901,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
901 skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; 901 skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
902 } 902 }
903 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 903 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
904 get_page(skb_shinfo(skb)->frags[i].page); 904 skb_frag_ref(skb, i);
905 905
906 if (skb_has_frag_list(skb)) 906 if (skb_has_frag_list(skb))
907 skb_clone_fraglist(skb); 907 skb_clone_fraglist(skb);
@@ -1181,7 +1181,7 @@ drop_pages:
1181 skb_shinfo(skb)->nr_frags = i; 1181 skb_shinfo(skb)->nr_frags = i;
1182 1182
1183 for (; i < nfrags; i++) 1183 for (; i < nfrags; i++)
1184 put_page(skb_shinfo(skb)->frags[i].page); 1184 skb_frag_unref(skb, i);
1185 1185
1186 if (skb_has_frag_list(skb)) 1186 if (skb_has_frag_list(skb))
1187 skb_drop_fraglist(skb); 1187 skb_drop_fraglist(skb);
@@ -1350,7 +1350,7 @@ pull_pages:
1350 k = 0; 1350 k = 0;
1351 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1351 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1352 if (skb_shinfo(skb)->frags[i].size <= eat) { 1352 if (skb_shinfo(skb)->frags[i].size <= eat) {
1353 put_page(skb_shinfo(skb)->frags[i].page); 1353 skb_frag_unref(skb, i);
1354 eat -= skb_shinfo(skb)->frags[i].size; 1354 eat -= skb_shinfo(skb)->frags[i].size;
1355 } else { 1355 } else {
1356 skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; 1356 skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];
@@ -1609,7 +1609,8 @@ static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
1609 for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) { 1609 for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) {
1610 const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; 1610 const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
1611 1611
1612 if (__splice_segment(f->page, f->page_offset, f->size, 1612 if (__splice_segment(skb_frag_page(f),
1613 f->page_offset, f->size,
1613 offset, len, skb, spd, 0, sk, pipe)) 1614 offset, len, skb, spd, 0, sk, pipe))
1614 return 1; 1615 return 1;
1615 } 1616 }
@@ -2154,7 +2155,7 @@ static inline void skb_split_no_header(struct sk_buff *skb,
2154 * where splitting is expensive. 2155 * where splitting is expensive.
2155 * 2. Split is accurately. We make this. 2156 * 2. Split is accurately. We make this.
2156 */ 2157 */
2157 get_page(skb_shinfo(skb)->frags[i].page); 2158 skb_frag_ref(skb, i);
2158 skb_shinfo(skb1)->frags[0].page_offset += len - pos; 2159 skb_shinfo(skb1)->frags[0].page_offset += len - pos;
2159 skb_shinfo(skb1)->frags[0].size -= len - pos; 2160 skb_shinfo(skb1)->frags[0].size -= len - pos;
2160 skb_shinfo(skb)->frags[i].size = len - pos; 2161 skb_shinfo(skb)->frags[i].size = len - pos;
@@ -2229,7 +2230,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
2229 * commit all, so that we don't have to undo partial changes 2230 * commit all, so that we don't have to undo partial changes
2230 */ 2231 */
2231 if (!to || 2232 if (!to ||
2232 !skb_can_coalesce(tgt, to, fragfrom->page, fragfrom->page_offset)) { 2233 !skb_can_coalesce(tgt, to, skb_frag_page(fragfrom),
2234 fragfrom->page_offset)) {
2233 merge = -1; 2235 merge = -1;
2234 } else { 2236 } else {
2235 merge = to - 1; 2237 merge = to - 1;
@@ -2276,7 +2278,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
2276 to++; 2278 to++;
2277 2279
2278 } else { 2280 } else {
2279 get_page(fragfrom->page); 2281 __skb_frag_ref(fragfrom);
2280 fragto->page = fragfrom->page; 2282 fragto->page = fragfrom->page;
2281 fragto->page_offset = fragfrom->page_offset; 2283 fragto->page_offset = fragfrom->page_offset;
2282 fragto->size = todo; 2284 fragto->size = todo;
@@ -2298,7 +2300,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
2298 fragto = &skb_shinfo(tgt)->frags[merge]; 2300 fragto = &skb_shinfo(tgt)->frags[merge];
2299 2301
2300 fragto->size += fragfrom->size; 2302 fragto->size += fragfrom->size;
2301 put_page(fragfrom->page); 2303 __skb_frag_unref(fragfrom);
2302 } 2304 }
2303 2305
2304 /* Reposition in the original skb */ 2306 /* Reposition in the original skb */
@@ -2543,8 +2545,7 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
2543 left = PAGE_SIZE - frag->page_offset; 2545 left = PAGE_SIZE - frag->page_offset;
2544 copy = (length > left)? left : length; 2546 copy = (length > left)? left : length;
2545 2547
2546 ret = getfrag(from, (page_address(frag->page) + 2548 ret = getfrag(from, skb_frag_address(frag) + frag->size,
2547 frag->page_offset + frag->size),
2548 offset, copy, 0, skb); 2549 offset, copy, 0, skb);
2549 if (ret < 0) 2550 if (ret < 0)
2550 return -EFAULT; 2551 return -EFAULT;
@@ -2696,7 +2697,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, u32 features)
2696 2697
2697 while (pos < offset + len && i < nfrags) { 2698 while (pos < offset + len && i < nfrags) {
2698 *frag = skb_shinfo(skb)->frags[i]; 2699 *frag = skb_shinfo(skb)->frags[i];
2699 get_page(frag->page); 2700 __skb_frag_ref(frag);
2700 size = frag->size; 2701 size = frag->size;
2701 2702
2702 if (pos < offset) { 2703 if (pos < offset) {
@@ -2919,7 +2920,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
2919 2920
2920 if (copy > len) 2921 if (copy > len)
2921 copy = len; 2922 copy = len;
2922 sg_set_page(&sg[elt], frag->page, copy, 2923 sg_set_page(&sg[elt], skb_frag_page(frag), copy,
2923 frag->page_offset+offset-start); 2924 frag->page_offset+offset-start);
2924 elt++; 2925 elt++;
2925 if (!(len -= copy)) 2926 if (!(len -= copy))
diff --git a/net/core/sock.c b/net/core/sock.c
index 9997026b44b2..b29ab61b029c 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1533,7 +1533,6 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
1533 skb_shinfo(skb)->nr_frags = npages; 1533 skb_shinfo(skb)->nr_frags = npages;
1534 for (i = 0; i < npages; i++) { 1534 for (i = 0; i < npages; i++) {
1535 struct page *page; 1535 struct page *page;
1536 skb_frag_t *frag;
1537 1536
1538 page = alloc_pages(sk->sk_allocation, 0); 1537 page = alloc_pages(sk->sk_allocation, 0);
1539 if (!page) { 1538 if (!page) {
@@ -1543,12 +1542,11 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
1543 goto failure; 1542 goto failure;
1544 } 1543 }
1545 1544
1546 frag = &skb_shinfo(skb)->frags[i]; 1545 __skb_fill_page_desc(skb, i,
1547 frag->page = page; 1546 page, 0,
1548 frag->page_offset = 0; 1547 (data_len >= PAGE_SIZE ?
1549 frag->size = (data_len >= PAGE_SIZE ? 1548 PAGE_SIZE :
1550 PAGE_SIZE : 1549 data_len));
1551 data_len);
1552 data_len -= PAGE_SIZE; 1550 data_len -= PAGE_SIZE;
1553 } 1551 }
1554 1552
diff --git a/net/core/user_dma.c b/net/core/user_dma.c
index 25d717ebc92e..34e9664cae3b 100644
--- a/net/core/user_dma.c
+++ b/net/core/user_dma.c
@@ -78,7 +78,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan,
78 copy = end - offset; 78 copy = end - offset;
79 if (copy > 0) { 79 if (copy > 0) {
80 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 80 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
81 struct page *page = frag->page; 81 struct page *page = skb_frag_page(frag);
82 82
83 if (copy > len) 83 if (copy > len)
84 copy = len; 84 copy = len;