diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-01-29 09:19:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-29 19:33:03 -0500 |
commit | 86911732d3996a9da07914b280621450111bb6da (patch) | |
tree | e787240d5ba869ddf4d0adfc3f9c69e0372e96ef /include/linux/netdevice.h | |
parent | 5d0d9be8ef456afc6c3fb5f8aad06ef19b704b05 (diff) |
gro: Avoid copying headers of unmerged packets
Unfortunately simplicity isn't always the best. The fraginfo
interface turned out to be suboptimal. The problem was quite
obvious. For every packet, we have to copy the headers from
the frags structure into skb->head, even though for 99% of the
packets this part is immediately thrown away after the merge.
LRO didn't have this problem because it directly read the headers
from the frags structure.
This patch attempts to address this by creating an interface
that allows GRO to access the headers in the first frag without
having to copy it. Because all drivers that use frags place the
headers in the first frag this optimisation should be enough.
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 | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 20419508eec1..7a5057fbb7cd 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -984,6 +984,9 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, | |||
984 | void netif_napi_del(struct napi_struct *napi); | 984 | void netif_napi_del(struct napi_struct *napi); |
985 | 985 | ||
986 | struct napi_gro_cb { | 986 | struct napi_gro_cb { |
987 | /* This indicates where we are processing relative to skb->data. */ | ||
988 | int data_offset; | ||
989 | |||
987 | /* This is non-zero if the packet may be of the same flow. */ | 990 | /* This is non-zero if the packet may be of the same flow. */ |
988 | int same_flow; | 991 | int same_flow; |
989 | 992 | ||
@@ -1087,6 +1090,29 @@ extern int dev_restart(struct net_device *dev); | |||
1087 | #ifdef CONFIG_NETPOLL_TRAP | 1090 | #ifdef CONFIG_NETPOLL_TRAP |
1088 | extern int netpoll_trap(void); | 1091 | extern int netpoll_trap(void); |
1089 | #endif | 1092 | #endif |
1093 | extern void *skb_gro_header(struct sk_buff *skb, unsigned int hlen); | ||
1094 | extern int skb_gro_receive(struct sk_buff **head, | ||
1095 | struct sk_buff *skb); | ||
1096 | |||
1097 | static inline unsigned int skb_gro_offset(const struct sk_buff *skb) | ||
1098 | { | ||
1099 | return NAPI_GRO_CB(skb)->data_offset; | ||
1100 | } | ||
1101 | |||
1102 | static inline unsigned int skb_gro_len(const struct sk_buff *skb) | ||
1103 | { | ||
1104 | return skb->len - NAPI_GRO_CB(skb)->data_offset; | ||
1105 | } | ||
1106 | |||
1107 | static inline void skb_gro_pull(struct sk_buff *skb, unsigned int len) | ||
1108 | { | ||
1109 | NAPI_GRO_CB(skb)->data_offset += len; | ||
1110 | } | ||
1111 | |||
1112 | static inline void skb_gro_reset_offset(struct sk_buff *skb) | ||
1113 | { | ||
1114 | NAPI_GRO_CB(skb)->data_offset = 0; | ||
1115 | } | ||
1090 | 1116 | ||
1091 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, | 1117 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, |
1092 | unsigned short type, | 1118 | unsigned short type, |