diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-05-26 14:50:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-27 06:25:57 -0400 |
commit | 78d3fd0b7de844a6dad56e9620fc9d2271b32ab9 (patch) | |
tree | e79c910646deccc50f5a108782f66cebffafa4d8 /include/linux/netdevice.h | |
parent | 67147ba99aeb48f2863e03b68e090088a34c1b5d (diff) |
gro: Only use skb_gro_header for completely non-linear packets
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>
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r-- | include/linux/netdevice.h | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 61890ed0bcf2..d1afc3b64854 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1135,22 +1135,23 @@ static inline void *skb_gro_header(struct sk_buff *skb, unsigned int hlen) | |||
1135 | 1135 | ||
1136 | hlen += offset; | 1136 | hlen += offset; |
1137 | if (!NAPI_GRO_CB(skb)->frag0 || | 1137 | if (!NAPI_GRO_CB(skb)->frag0 || |
1138 | unlikely(skb_shinfo(skb)->frags[0].size + skb_headlen(skb) < hlen)) | 1138 | unlikely(skb_shinfo(skb)->frags[0].size < hlen)) { |
1139 | NAPI_GRO_CB(skb)->frag0 = NULL; | ||
1139 | return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; | 1140 | return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; |
1141 | } | ||
1140 | 1142 | ||
1141 | return NAPI_GRO_CB(skb)->frag0 + offset; | 1143 | return NAPI_GRO_CB(skb)->frag0 + offset; |
1142 | } | 1144 | } |
1143 | 1145 | ||
1144 | static inline void *skb_gro_mac_header(struct sk_buff *skb) | 1146 | static inline void *skb_gro_mac_header(struct sk_buff *skb) |
1145 | { | 1147 | { |
1146 | return skb_headlen(skb) ? skb_mac_header(skb) : | 1148 | return NAPI_GRO_CB(skb)->frag0 ?: skb_mac_header(skb); |
1147 | NAPI_GRO_CB(skb)->frag0; | ||
1148 | } | 1149 | } |
1149 | 1150 | ||
1150 | static inline void *skb_gro_network_header(struct sk_buff *skb) | 1151 | static inline void *skb_gro_network_header(struct sk_buff *skb) |
1151 | { | 1152 | { |
1152 | return skb_headlen(skb) ? skb_network_header(skb) : | 1153 | return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) + |
1153 | NAPI_GRO_CB(skb)->frag0 + skb_network_offset(skb); | 1154 | skb_network_offset(skb); |
1154 | } | 1155 | } |
1155 | 1156 | ||
1156 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, | 1157 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, |