diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-02-08 13:00:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-08 23:22:18 -0500 |
commit | aa4b9f533ed5a22952e038b9fac2447ccc682124 (patch) | |
tree | 91722b13a63dcd0e49695388e633cfa91b856b80 /include/linux/etherdevice.h | |
parent | 4ae5544f9a33e4ae306e337f96951eb3ff2df6d9 (diff) |
gro: Optimise Ethernet header comparison
This patch optimises the Ethernet header comparison to use 2-byte
and 4-byte xors instead of memcmp. In order to facilitate this,
the actual comparison is now carried out by the callers of the
shared dev_gro_receive function.
This has a significant impact when receiving 1500B packets through
10GbE.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/etherdevice.h')
-rw-r--r-- | include/linux/etherdevice.h | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 1cb0f0b90926..a1f17abba7dc 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -184,4 +184,25 @@ static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2], | |||
184 | } | 184 | } |
185 | #endif /* __KERNEL__ */ | 185 | #endif /* __KERNEL__ */ |
186 | 186 | ||
187 | /** | ||
188 | * compare_ether_header - Compare two Ethernet headers | ||
189 | * @a: Pointer to Ethernet header | ||
190 | * @b: Pointer to Ethernet header | ||
191 | * | ||
192 | * Compare two ethernet headers, returns 0 if equal. | ||
193 | * This assumes that the network header (i.e., IP header) is 4-byte | ||
194 | * aligned OR the platform can handle unaligned access. This is the | ||
195 | * case for all packets coming into netif_receive_skb or similar | ||
196 | * entry points. | ||
197 | */ | ||
198 | |||
199 | static inline int compare_ether_header(const void *a, const void *b) | ||
200 | { | ||
201 | u32 *a32 = (u32 *)((u8 *)a + 2); | ||
202 | u32 *b32 = (u32 *)((u8 *)b + 2); | ||
203 | |||
204 | return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) | | ||
205 | (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]); | ||
206 | } | ||
207 | |||
187 | #endif /* _LINUX_ETHERDEVICE_H */ | 208 | #endif /* _LINUX_ETHERDEVICE_H */ |