summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-02-08 18:00:37 +0000
committerDavid S. Miller <davem@davemloft.net>2009-02-08 20:22:18 -0800
commitaa4b9f533ed5a22952e038b9fac2447ccc682124 (patch)
tree91722b13a63dcd0e49695388e633cfa91b856b80 /include
parent4ae5544f9a33e4ae306e337f96951eb3ff2df6d9 (diff)
downloadkernel-crypto-aa4b9f533ed5a22952e038b9fac2447ccc682124.tar.gz
kernel-crypto-aa4b9f533ed5a22952e038b9fac2447ccc682124.tar.xz
kernel-crypto-aa4b9f533ed5a22952e038b9fac2447ccc682124.zip
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')
-rw-r--r--include/linux/etherdevice.h21
-rw-r--r--include/linux/netdevice.h7
2 files changed, 28 insertions, 0 deletions
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 1cb0f0b9092..a1f17abba7d 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],
}
#endif /* __KERNEL__ */
+/**
+ * compare_ether_header - Compare two Ethernet headers
+ * @a: Pointer to Ethernet header
+ * @b: Pointer to Ethernet header
+ *
+ * Compare two ethernet headers, returns 0 if equal.
+ * This assumes that the network header (i.e., IP header) is 4-byte
+ * aligned OR the platform can handle unaligned access. This is the
+ * case for all packets coming into netif_receive_skb or similar
+ * entry points.
+ */
+
+static inline int compare_ether_header(const void *a, const void *b)
+{
+ u32 *a32 = (u32 *)((u8 *)a + 2);
+ u32 *b32 = (u32 *)((u8 *)b + 2);
+
+ return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
+ (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
+}
+
#endif /* _LINUX_ETHERDEVICE_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9ee344bc6c1..355662aac94 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1117,6 +1117,13 @@ static inline void skb_gro_reset_offset(struct sk_buff *skb)
NAPI_GRO_CB(skb)->data_offset = 0;
}
+static inline void *skb_gro_mac_header(struct sk_buff *skb)
+{
+ return skb_mac_header(skb) < skb->data ? skb_mac_header(skb) :
+ page_address(skb_shinfo(skb)->frags[0].page) +
+ skb_shinfo(skb)->frags[0].page_offset;
+}
+
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
const void *daddr, const void *saddr,