diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-05-26 14:50:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-27 06:26:04 -0400 |
commit | 66e92fcf1ded5dd0da30d016ed47882eb183ec71 (patch) | |
tree | be7f0fc2415ada8eb5030af53f3063375c381d47 /net/core | |
parent | cb18978cbf454c236db5e4191a12ef71eef9b3a0 (diff) |
gro: Nasty optimisations for page frags in skb_gro_receive
This patch reverses the direction of the frags array copy in
skb_gro_receive in order simplify the loop conditional. It
also avoids touching the first element of the original frags
array.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/skbuff.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 168e949df6a1..19afb18abae9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2676,21 +2676,26 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2676 | goto merge; | 2676 | goto merge; |
2677 | else if (headlen <= offset) { | 2677 | else if (headlen <= offset) { |
2678 | skb_frag_t *frag; | 2678 | skb_frag_t *frag; |
2679 | int i; | 2679 | skb_frag_t *frag2; |
2680 | int i = skb_shinfo(skb)->nr_frags; | ||
2681 | int nr_frags = skb_shinfo(p)->nr_frags + i; | ||
2682 | |||
2683 | offset -= headlen; | ||
2680 | 2684 | ||
2681 | if (skb_shinfo(p)->nr_frags + skb_shinfo(skb)->nr_frags > | 2685 | if (nr_frags > MAX_SKB_FRAGS) |
2682 | MAX_SKB_FRAGS) | ||
2683 | return -E2BIG; | 2686 | return -E2BIG; |
2684 | 2687 | ||
2685 | skb_shinfo(skb)->frags[0].page_offset += offset - headlen; | 2688 | skb_shinfo(p)->nr_frags = nr_frags; |
2686 | skb_shinfo(skb)->frags[0].size -= offset - headlen; | 2689 | skb_shinfo(skb)->nr_frags = 0; |
2687 | 2690 | ||
2688 | frag = skb_shinfo(p)->frags + skb_shinfo(p)->nr_frags; | 2691 | frag = skb_shinfo(p)->frags + nr_frags; |
2689 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 2692 | frag2 = skb_shinfo(skb)->frags + i; |
2690 | *frag++ = skb_shinfo(skb)->frags[i]; | 2693 | do { |
2694 | *--frag = *--frag2; | ||
2695 | } while (--i); | ||
2691 | 2696 | ||
2692 | skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags; | 2697 | frag->page_offset += offset; |
2693 | skb_shinfo(skb)->nr_frags = 0; | 2698 | frag->size -= offset; |
2694 | 2699 | ||
2695 | skb->truesize -= skb->data_len; | 2700 | skb->truesize -= skb->data_len; |
2696 | skb->len -= skb->data_len; | 2701 | skb->len -= skb->data_len; |