aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-05-26 14:50:28 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-27 06:26:01 -0400
commita5b1cf288d4200506ab62fbb86cc81ace948a306 (patch)
treec95339866f4d67220d111811a92e5c6b79de6ab4 /net/core/dev.c
parent7489594cb249aeb178287c9a43a9e4f366044259 (diff)
gro: Avoid unnecessary comparison after skb_gro_header
For the overwhelming majority of cases, skb_gro_header's return value cannot be NULL. Yet we must check it because of its current form. This patch splits it up into multiple functions in order to avoid this. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index b1722a2d1fbe..cd29e613bc5a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2590,17 +2590,24 @@ struct sk_buff *napi_frags_skb(struct napi_struct *napi)
2590{ 2590{
2591 struct sk_buff *skb = napi->skb; 2591 struct sk_buff *skb = napi->skb;
2592 struct ethhdr *eth; 2592 struct ethhdr *eth;
2593 unsigned int hlen;
2594 unsigned int off;
2593 2595
2594 napi->skb = NULL; 2596 napi->skb = NULL;
2595 2597
2596 skb_reset_mac_header(skb); 2598 skb_reset_mac_header(skb);
2597 skb_gro_reset_offset(skb); 2599 skb_gro_reset_offset(skb);
2598 2600
2599 eth = skb_gro_header(skb, sizeof(*eth)); 2601 off = skb_gro_offset(skb);
2600 if (!eth) { 2602 hlen = off + sizeof(*eth);
2601 napi_reuse_skb(napi, skb); 2603 eth = skb_gro_header_fast(skb, off);
2602 skb = NULL; 2604 if (skb_gro_header_hard(skb, hlen)) {
2603 goto out; 2605 eth = skb_gro_header_slow(skb, hlen, off);
2606 if (unlikely(!eth)) {
2607 napi_reuse_skb(napi, skb);
2608 skb = NULL;
2609 goto out;
2610 }
2604 } 2611 }
2605 2612
2606 skb_gro_pull(skb, sizeof(*eth)); 2613 skb_gro_pull(skb, sizeof(*eth));