gro: Only use skb_gro_header for completely non-linear packets
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 26 May 2009 18:50:23 +0000 (18:50 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 27 May 2009 10:25:57 +0000 (03:25 -0700)
Currently skb_gro_header is used for packets which put the hardware
header in skb->data with the rest in frags.  Since the drivers that
need this optimisation all provide completely non-linear packets,
we can gain extra optimisations by only performing the frag0
optimisation for completely non-linear packets.

In particular, we can simply test frag0 (instead of skb_headlen)
to see whether the optimisation is in force.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdevice.h
net/core/dev.c

index 61890ed..d1afc3b 100644 (file)
@@ -1135,22 +1135,23 @@ static inline void *skb_gro_header(struct sk_buff *skb, unsigned int hlen)
 
        hlen += offset;
        if (!NAPI_GRO_CB(skb)->frag0 ||
-           unlikely(skb_shinfo(skb)->frags[0].size + skb_headlen(skb) < hlen))
+           unlikely(skb_shinfo(skb)->frags[0].size < hlen)) {
+               NAPI_GRO_CB(skb)->frag0 = NULL;
                return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
+       }
 
        return NAPI_GRO_CB(skb)->frag0 + offset;
 }
 
 static inline void *skb_gro_mac_header(struct sk_buff *skb)
 {
-       return skb_headlen(skb) ? skb_mac_header(skb) :
-              NAPI_GRO_CB(skb)->frag0;
+       return NAPI_GRO_CB(skb)->frag0 ?: skb_mac_header(skb);
 }
 
 static inline void *skb_gro_network_header(struct sk_buff *skb)
 {
-       return skb_headlen(skb) ? skb_network_header(skb) :
-              NAPI_GRO_CB(skb)->frag0 + skb_network_offset(skb);
+       return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) +
+              skb_network_offset(skb);
 }
 
 static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
index bdb1a73..f9d90c5 100644 (file)
@@ -2510,7 +2510,8 @@ void skb_gro_reset_offset(struct sk_buff *skb)
        NAPI_GRO_CB(skb)->data_offset = 0;
        NAPI_GRO_CB(skb)->frag0 = NULL;
 
-       if (!skb_headlen(skb) && !PageHighMem(skb_shinfo(skb)->frags[0].page))
+       if (skb->mac_header == skb->tail &&
+           !PageHighMem(skb_shinfo(skb)->frags[0].page))
                NAPI_GRO_CB(skb)->frag0 =
                        page_address(skb_shinfo(skb)->frags[0].page) +
                        skb_shinfo(skb)->frags[0].page_offset;