All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] skb fragment API: convert network core and protocols
@ 2011-08-23  9:44 Ian Campbell
  2011-08-23  9:44 ` [PATCH 1/4] net: convert core to skb paged frag APIs Ian Campbell
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Ian Campbell @ 2011-08-23  9:44 UTC (permalink / raw)
  To: netdev

The following series converts the net core and protocol stacks to the
SKB pages fragment API introduced in 131ea6675c76.

This is part of my series to enable visibility into SKB paged fragment's
lifecycles, [0] contains some more background and rationale but
basically the completed series will allow entities which inject pages
into the networking stack to receive a notification when the stack has
really finished with those pages (i.e. including retransmissions,
clones, pull-ups etc) and not just when the original skb is finished
with, which is beneficial to many subsystems which wish to inject pages
into the network stack without giving up full ownership of those page's
lifecycle. It implements something broadly along the lines of what was
described in [1].

Cheers,
Ian.

[0] http://marc.info/?l=linux-netdev&m=131072801125521&w=2
[1] http://marc.info/?l=linux-netdev&m=130925719513084&w=2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] net: convert core to skb paged frag APIs
  2011-08-23  9:44 [PATCH 0/4] skb fragment API: convert network core and protocols Ian Campbell
@ 2011-08-23  9:44 ` Ian Campbell
  2011-08-23 18:34   ` Michał Mirosław
  2011-08-25  0:52   ` David Miller
  2011-08-23  9:44 ` [PATCH 2/4] net: ipv4: convert to SKB " Ian Campbell
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Ian Campbell @ 2011-08-23  9:44 UTC (permalink / raw)
  To: netdev
  Cc: Ian Campbell, David S. Miller, Eric Dumazet, Michał Mirosław

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
---
 include/linux/skbuff.h |    4 ++--
 net/core/datagram.c    |    8 ++++----
 net/core/dev.c         |   16 +++++++++-------
 net/core/kmap_skb.h    |    2 +-
 net/core/pktgen.c      |    3 +--
 net/core/skbuff.c      |   29 +++++++++++++++--------------
 net/core/sock.c        |   12 +++++-------
 net/core/user_dma.c    |    2 +-
 8 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7b0e177..8d42628 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,
 }
 
 static inline int skb_can_coalesce(struct sk_buff *skb, int i,
-				   struct page *page, int off)
+				   const struct page *page, int off)
 {
 	if (i) {
 		struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1];
 
-		return page == frag->page &&
+		return page == skb_frag_page(frag) &&
 		       off == frag->page_offset + frag->size;
 	}
 	return 0;
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 18ac112..6449bed 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,
 			int err;
 			u8  *vaddr;
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			struct page *page = frag->page;
+			struct page *page = skb_frag_page(frag);
 
 			if (copy > len)
 				copy = len;
@@ -418,7 +418,7 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
 			int err;
 			u8  *vaddr;
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			struct page *page = frag->page;
+			struct page *page = skb_frag_page(frag);
 
 			if (copy > len)
 				copy = len;
@@ -508,7 +508,7 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
 			int err;
 			u8  *vaddr;
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			struct page *page = frag->page;
+			struct page *page = skb_frag_page(frag);
 
 			if (copy > len)
 				copy = len;
@@ -594,7 +594,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
 			int err = 0;
 			u8  *vaddr;
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			struct page *page = frag->page;
+			struct page *page = skb_frag_page(frag);
 
 			if (copy > len)
 				copy = len;
diff --git a/net/core/dev.c b/net/core/dev.c
index a4306f7..4053008 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)
 #ifdef CONFIG_HIGHMEM
 	int i;
 	if (!(dev->features & NETIF_F_HIGHDMA)) {
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-			if (PageHighMem(skb_shinfo(skb)->frags[i].page))
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			if (PageHighMem(skb_frag_page(frag)))
 				return 1;
+		}
 	}
 
 	if (PCI_DMA_BUS_IS_PHYS) {
@@ -1960,7 +1962,8 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 		if (!pdev)
 			return 0;
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			dma_addr_t addr = page_to_phys(skb_shinfo(skb)->frags[i].page);
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			dma_addr_t addr = page_to_phys(skb_frag_page(frag));
 			if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
 				return 1;
 		}
@@ -3472,7 +3475,7 @@ pull:
 		skb_shinfo(skb)->frags[0].size -= grow;
 
 		if (unlikely(!skb_shinfo(skb)->frags[0].size)) {
-			put_page(skb_shinfo(skb)->frags[0].page);
+			skb_frag_unref(skb, 0);
 			memmove(skb_shinfo(skb)->frags,
 				skb_shinfo(skb)->frags + 1,
 				--skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
@@ -3536,10 +3539,9 @@ void skb_gro_reset_offset(struct sk_buff *skb)
 	NAPI_GRO_CB(skb)->frag0_len = 0;
 
 	if (skb->mac_header == skb->tail &&
-	    !PageHighMem(skb_shinfo(skb)->frags[0].page)) {
+	    !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) {
 		NAPI_GRO_CB(skb)->frag0 =
-			page_address(skb_shinfo(skb)->frags[0].page) +
-			skb_shinfo(skb)->frags[0].page_offset;
+			skb_frag_address(&skb_shinfo(skb)->frags[0]);
 		NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size;
 	}
 }
diff --git a/net/core/kmap_skb.h b/net/core/kmap_skb.h
index 283c2b9..81e1ed7 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)
 
 	local_bh_disable();
 #endif
-	return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ);
+	return kmap_atomic(skb_frag_page(frag), KM_SKB_DATA_SOFTIRQ);
 }
 
 static inline void kunmap_skb_frag(void *vaddr)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index e35a6fb..796044a 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,
 				if (!pkt_dev->page)
 					break;
 			}
-			skb_shinfo(skb)->frags[i].page = pkt_dev->page;
-			get_page(pkt_dev->page);
+			skb_frag_set_page(skb, i, pkt_dev->page);
 			skb_shinfo(skb)->frags[i].page_offset = 0;
 			/*last fragment, fill rest of data*/
 			if (i == (frags - 1))
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e27334e..296afd0 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -326,7 +326,7 @@ static void skb_release_data(struct sk_buff *skb)
 		if (skb_shinfo(skb)->nr_frags) {
 			int i;
 			for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-				put_page(skb_shinfo(skb)->frags[i].page);
+				skb_frag_unref(skb, i);
 		}
 
 		/*
@@ -809,7 +809,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
 		}
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
-			get_page(skb_shinfo(n)->frags[i].page);
+			skb_frag_ref(skb, i);
 		}
 		skb_shinfo(n)->nr_frags = i;
 	}
@@ -901,7 +901,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
 			skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
 		}
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-			get_page(skb_shinfo(skb)->frags[i].page);
+			skb_frag_ref(skb, i);
 
 		if (skb_has_frag_list(skb))
 			skb_clone_fraglist(skb);
@@ -1181,7 +1181,7 @@ drop_pages:
 		skb_shinfo(skb)->nr_frags = i;
 
 		for (; i < nfrags; i++)
-			put_page(skb_shinfo(skb)->frags[i].page);
+			skb_frag_unref(skb, i);
 
 		if (skb_has_frag_list(skb))
 			skb_drop_fraglist(skb);
@@ -1350,7 +1350,7 @@ pull_pages:
 	k = 0;
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		if (skb_shinfo(skb)->frags[i].size <= eat) {
-			put_page(skb_shinfo(skb)->frags[i].page);
+			skb_frag_unref(skb, i);
 			eat -= skb_shinfo(skb)->frags[i].size;
 		} else {
 			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,
 	for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) {
 		const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
 
-		if (__splice_segment(f->page, f->page_offset, f->size,
+		if (__splice_segment(skb_frag_page(f),
+				     f->page_offset, f->size,
 				     offset, len, skb, spd, 0, sk, pipe))
 			return 1;
 	}
@@ -2154,7 +2155,7 @@ static inline void skb_split_no_header(struct sk_buff *skb,
 				 *    where splitting is expensive.
 				 * 2. Split is accurately. We make this.
 				 */
-				get_page(skb_shinfo(skb)->frags[i].page);
+				skb_frag_ref(skb, i);
 				skb_shinfo(skb1)->frags[0].page_offset += len - pos;
 				skb_shinfo(skb1)->frags[0].size -= len - pos;
 				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)
 	 * commit all, so that we don't have to undo partial changes
 	 */
 	if (!to ||
-	    !skb_can_coalesce(tgt, to, fragfrom->page, fragfrom->page_offset)) {
+	    !skb_can_coalesce(tgt, to, skb_frag_page(fragfrom),
+			      fragfrom->page_offset)) {
 		merge = -1;
 	} else {
 		merge = to - 1;
@@ -2276,7 +2278,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
 			to++;
 
 		} else {
-			get_page(fragfrom->page);
+			__skb_frag_ref(fragfrom);
 			fragto->page = fragfrom->page;
 			fragto->page_offset = fragfrom->page_offset;
 			fragto->size = todo;
@@ -2298,7 +2300,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
 		fragto = &skb_shinfo(tgt)->frags[merge];
 
 		fragto->size += fragfrom->size;
-		put_page(fragfrom->page);
+		__skb_frag_unref(fragfrom);
 	}
 
 	/* Reposition in the original skb */
@@ -2543,8 +2545,7 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
 		left = PAGE_SIZE - frag->page_offset;
 		copy = (length > left)? left : length;
 
-		ret = getfrag(from, (page_address(frag->page) +
-			    frag->page_offset + frag->size),
+		ret = getfrag(from, skb_frag_address(frag) + frag->size,
 			    offset, copy, 0, skb);
 		if (ret < 0)
 			return -EFAULT;
@@ -2696,7 +2697,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, u32 features)
 
 		while (pos < offset + len && i < nfrags) {
 			*frag = skb_shinfo(skb)->frags[i];
-			get_page(frag->page);
+			__skb_frag_ref(frag);
 			size = frag->size;
 
 			if (pos < offset) {
@@ -2919,7 +2920,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg_set_page(&sg[elt], frag->page, copy,
+			sg_set_page(&sg[elt], skb_frag_page(frag), copy,
 					frag->page_offset+offset-start);
 			elt++;
 			if (!(len -= copy))
diff --git a/net/core/sock.c b/net/core/sock.c
index 9997026..b29ab61 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,
 				skb_shinfo(skb)->nr_frags = npages;
 				for (i = 0; i < npages; i++) {
 					struct page *page;
-					skb_frag_t *frag;
 
 					page = alloc_pages(sk->sk_allocation, 0);
 					if (!page) {
@@ -1543,12 +1542,11 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
 						goto failure;
 					}
 
-					frag = &skb_shinfo(skb)->frags[i];
-					frag->page = page;
-					frag->page_offset = 0;
-					frag->size = (data_len >= PAGE_SIZE ?
-						      PAGE_SIZE :
-						      data_len);
+					__skb_fill_page_desc(skb, i,
+							page, 0,
+							(data_len >= PAGE_SIZE ?
+							 PAGE_SIZE :
+							 data_len));
 					data_len -= PAGE_SIZE;
 				}
 
diff --git a/net/core/user_dma.c b/net/core/user_dma.c
index 25d717e..34e9664 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,
 		copy = end - offset;
 		if (copy > 0) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			struct page *page = frag->page;
+			struct page *page = skb_frag_page(frag);
 
 			if (copy > len)
 				copy = len;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] net: ipv4: convert to SKB frag APIs
  2011-08-23  9:44 [PATCH 0/4] skb fragment API: convert network core and protocols Ian Campbell
  2011-08-23  9:44 ` [PATCH 1/4] net: convert core to skb paged frag APIs Ian Campbell
@ 2011-08-23  9:44 ` Ian Campbell
  2011-08-25  0:52   ` David Miller
  2011-08-23  9:45 ` [PATCH 3/4] net: ipv6: " Ian Campbell
  2011-08-23  9:45 ` [PATCH 4/4] net: xfrm: " Ian Campbell
  3 siblings, 1 reply; 11+ messages in thread
From: Ian Campbell @ 2011-08-23  9:44 UTC (permalink / raw)
  To: netdev
  Cc: Ian Campbell, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6),
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: "Pekka Savola (ipv6)" <pekkas@netcore.fi>
Cc: James Morris <jmorris@namei.org>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: netdev@vger.kernel.org
---
 net/ipv4/inet_lro.c   |    2 +-
 net/ipv4/ip_output.c  |    7 ++++---
 net/ipv4/tcp.c        |    3 ++-
 net/ipv4/tcp_output.c |    2 +-
 4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index ef7ae60..8e6be5a 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -433,7 +433,7 @@ static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
 	if (!lro_mgr->get_frag_header ||
 	    lro_mgr->get_frag_header(frags, (void *)&mac_hdr, (void *)&iph,
 				     (void *)&tcph, &flags, priv)) {
-		mac_hdr = page_address(frags->page) + frags->page_offset;
+		mac_hdr = skb_frag_address(frags);
 		goto out1;
 	}
 
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8c65633..ae3bb14 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -989,13 +989,13 @@ alloc_new_skb:
 			if (page && (left = PAGE_SIZE - off) > 0) {
 				if (copy >= left)
 					copy = left;
-				if (page != frag->page) {
+				if (page != skb_frag_page(frag)) {
 					if (i == MAX_SKB_FRAGS) {
 						err = -EMSGSIZE;
 						goto error;
 					}
-					get_page(page);
 					skb_fill_page_desc(skb, i, page, off, 0);
+					skb_frag_ref(skb, i);
 					frag = &skb_shinfo(skb)->frags[i];
 				}
 			} else if (i < MAX_SKB_FRAGS) {
@@ -1015,7 +1015,8 @@ alloc_new_skb:
 				err = -EMSGSIZE;
 				goto error;
 			}
-			if (getfrag(from, page_address(frag->page)+frag->page_offset+frag->size, offset, copy, skb->len, skb) < 0) {
+			if (getfrag(from, skb_frag_address(frag)+frag->size,
+				    offset, copy, skb->len, skb) < 0) {
 				err = -EFAULT;
 				goto error;
 			}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 46febca..5fe632c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3035,7 +3035,8 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
 
 	for (i = 0; i < shi->nr_frags; ++i) {
 		const struct skb_frag_struct *f = &shi->frags[i];
-		sg_set_page(&sg, f->page, f->size, f->page_offset);
+		struct page *page = skb_frag_page(f);
+		sg_set_page(&sg, page, f->size, f->page_offset);
 		if (crypto_hash_update(desc, &sg, f->size))
 			return 1;
 	}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 882e0b0..0377c06 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1095,7 +1095,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
 	k = 0;
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		if (skb_shinfo(skb)->frags[i].size <= eat) {
-			put_page(skb_shinfo(skb)->frags[i].page);
+			skb_frag_unref(skb, i);
 			eat -= skb_shinfo(skb)->frags[i].size;
 		} else {
 			skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] net: ipv6: convert to SKB frag APIs
  2011-08-23  9:44 [PATCH 0/4] skb fragment API: convert network core and protocols Ian Campbell
  2011-08-23  9:44 ` [PATCH 1/4] net: convert core to skb paged frag APIs Ian Campbell
  2011-08-23  9:44 ` [PATCH 2/4] net: ipv4: convert to SKB " Ian Campbell
@ 2011-08-23  9:45 ` Ian Campbell
  2011-08-25  0:52   ` David Miller
  2011-08-23  9:45 ` [PATCH 4/4] net: xfrm: " Ian Campbell
  3 siblings, 1 reply; 11+ messages in thread
From: Ian Campbell @ 2011-08-23  9:45 UTC (permalink / raw)
  To: netdev
  Cc: Ian Campbell, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6),
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: "Pekka Savola (ipv6)" <pekkas@netcore.fi>
Cc: James Morris <jmorris@namei.org>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: netdev@vger.kernel.org
---
 net/ipv6/ip6_output.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4c882cf..835c04b 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1480,13 +1480,13 @@ alloc_new_skb:
 			if (page && (left = PAGE_SIZE - off) > 0) {
 				if (copy >= left)
 					copy = left;
-				if (page != frag->page) {
+				if (page != skb_frag_page(frag)) {
 					if (i == MAX_SKB_FRAGS) {
 						err = -EMSGSIZE;
 						goto error;
 					}
-					get_page(page);
 					skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
+					skb_frag_ref(skb, i);
 					frag = &skb_shinfo(skb)->frags[i];
 				}
 			} else if(i < MAX_SKB_FRAGS) {
@@ -1506,7 +1506,8 @@ alloc_new_skb:
 				err = -EMSGSIZE;
 				goto error;
 			}
-			if (getfrag(from, page_address(frag->page)+frag->page_offset+frag->size, offset, copy, skb->len, skb) < 0) {
+			if (getfrag(from, skb_frag_address(frag)+frag->size,
+				    offset, copy, skb->len, skb) < 0) {
 				err = -EFAULT;
 				goto error;
 			}
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] net: xfrm: convert to SKB frag APIs
  2011-08-23  9:44 [PATCH 0/4] skb fragment API: convert network core and protocols Ian Campbell
                   ` (2 preceding siblings ...)
  2011-08-23  9:45 ` [PATCH 3/4] net: ipv6: " Ian Campbell
@ 2011-08-23  9:45 ` Ian Campbell
  2011-08-25  0:52   ` David Miller
  3 siblings, 1 reply; 11+ messages in thread
From: Ian Campbell @ 2011-08-23  9:45 UTC (permalink / raw)
  To: netdev; +Cc: Ian Campbell, David S. Miller

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
 net/xfrm/xfrm_ipcomp.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index fc91ad7..f781b9a 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -70,26 +70,29 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
 
 	while ((scratch += len, dlen -= len) > 0) {
 		skb_frag_t *frag;
+		struct page *page;
 
 		err = -EMSGSIZE;
 		if (WARN_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS))
 			goto out;
 
 		frag = skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
-		frag->page = alloc_page(GFP_ATOMIC);
+		page = alloc_page(GFP_ATOMIC);
 
 		err = -ENOMEM;
-		if (!frag->page)
+		if (!page)
 			goto out;
 
+		__skb_frag_set_page(frag, page);
+
 		len = PAGE_SIZE;
 		if (dlen < len)
 			len = dlen;
 
-		memcpy(page_address(frag->page), scratch, len);
-
 		frag->page_offset = 0;
 		frag->size = len;
+		memcpy(skb_frag_address(frag), scratch, len);
+
 		skb->truesize += len;
 		skb->data_len += len;
 		skb->len += len;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] net: convert core to skb paged frag APIs
  2011-08-23  9:44 ` [PATCH 1/4] net: convert core to skb paged frag APIs Ian Campbell
@ 2011-08-23 18:34   ` Michał Mirosław
  2011-08-24  7:49     ` Ian Campbell
  2011-08-25  0:52   ` David Miller
  1 sibling, 1 reply; 11+ messages in thread
From: Michał Mirosław @ 2011-08-23 18:34 UTC (permalink / raw)
  To: Ian Campbell
  Cc: netdev, David S. Miller, Eric Dumazet, Michał Mirosław

2011/8/23 Ian Campbell <ian.campbell@citrix.com>:
> +               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
> +                       skb_frag_t *frag = &skb_shinfo(skb)->frags[i];

This is a rather common construct, so it might be worth it to
introduce something like for_each_skb_frag().

Best Regards,
Michał Mirosław

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] net: convert core to skb paged frag APIs
  2011-08-23 18:34   ` Michał Mirosław
@ 2011-08-24  7:49     ` Ian Campbell
  0 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2011-08-24  7:49 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: netdev, David S. Miller, Eric Dumazet, Michał Mirosław

On Tue, 2011-08-23 at 19:34 +0100, Michał Mirosław wrote:
> 2011/8/23 Ian Campbell <ian.campbell@citrix.com>:
> > +               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
> > +                       skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
> 
> This is a rather common construct, so it might be worth it to
> introduce something like for_each_skb_frag().

I agree. My first stab at this helper (which was untenable for other
reasons, I never posted it) had such a helper. I decided not to tackle
it on this pass since it touches a bunch of places which even this
enormous series doesn't. I've got it on my list to do some time after
this series as a cleanup though.

Some places want the frag nr and others want the skb_frag_t* so I think
you'd end up with
	for_each_skb_frag(skb, frag) { ... }
and
	for_each_skb_frag_nr(skb, i) { ... }
a few places use both frag and i within the loop but not enough to
warrant an explicit helper, I don't think.

An "skb_frag(skb, i)" helper for the &skb_shinfo(skb)->frags[i]
construct might be nice too.

Ian.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] net: convert core to skb paged frag APIs
  2011-08-23  9:44 ` [PATCH 1/4] net: convert core to skb paged frag APIs Ian Campbell
  2011-08-23 18:34   ` Michał Mirosław
@ 2011-08-25  0:52   ` David Miller
  1 sibling, 0 replies; 11+ messages in thread
From: David Miller @ 2011-08-25  0:52 UTC (permalink / raw)
  To: ian.campbell; +Cc: netdev, eric.dumazet, mirq-linux

From: Ian Campbell <ian.campbell@citrix.com>
Date: Tue, 23 Aug 2011 10:44:58 +0100

> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Applied.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] net: ipv4: convert to SKB frag APIs
  2011-08-23  9:44 ` [PATCH 2/4] net: ipv4: convert to SKB " Ian Campbell
@ 2011-08-25  0:52   ` David Miller
  0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2011-08-25  0:52 UTC (permalink / raw)
  To: ian.campbell; +Cc: netdev, kuznet, pekkas, jmorris, yoshfuji, kaber

From: Ian Campbell <ian.campbell@citrix.com>
Date: Tue, 23 Aug 2011 10:44:59 +0100

> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Applied.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] net: ipv6: convert to SKB frag APIs
  2011-08-23  9:45 ` [PATCH 3/4] net: ipv6: " Ian Campbell
@ 2011-08-25  0:52   ` David Miller
  0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2011-08-25  0:52 UTC (permalink / raw)
  To: ian.campbell; +Cc: netdev, kuznet, pekkas, jmorris, yoshfuji, kaber

From: Ian Campbell <ian.campbell@citrix.com>
Date: Tue, 23 Aug 2011 10:45:00 +0100

> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Applied.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] net: xfrm: convert to SKB frag APIs
  2011-08-23  9:45 ` [PATCH 4/4] net: xfrm: " Ian Campbell
@ 2011-08-25  0:52   ` David Miller
  0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2011-08-25  0:52 UTC (permalink / raw)
  To: ian.campbell; +Cc: netdev

From: Ian Campbell <ian.campbell@citrix.com>
Date: Tue, 23 Aug 2011 10:45:01 +0100

> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Applied.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-08-25  0:56 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-23  9:44 [PATCH 0/4] skb fragment API: convert network core and protocols Ian Campbell
2011-08-23  9:44 ` [PATCH 1/4] net: convert core to skb paged frag APIs Ian Campbell
2011-08-23 18:34   ` Michał Mirosław
2011-08-24  7:49     ` Ian Campbell
2011-08-25  0:52   ` David Miller
2011-08-23  9:44 ` [PATCH 2/4] net: ipv4: convert to SKB " Ian Campbell
2011-08-25  0:52   ` David Miller
2011-08-23  9:45 ` [PATCH 3/4] net: ipv6: " Ian Campbell
2011-08-25  0:52   ` David Miller
2011-08-23  9:45 ` [PATCH 4/4] net: xfrm: " Ian Campbell
2011-08-25  0:52   ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.