diff options
author | Joe Perches <joe@perches.com> | 2013-12-06 18:44:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-09 20:58:11 -0500 |
commit | 2c722fe1c821a100ca87fcc36e90a9bceb497c7c (patch) | |
tree | be96c28923670d0daa2119e414efa9c52991928d /include/linux/etherdevice.h | |
parent | d9cd4fe5ef4373e0f5b2e752b1859bee33bc5644 (diff) |
etherdevice: Optimize a few is_<foo>_ether_addr functions
If CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is set,
several is_<foo>_ether_addr functions can be slightly
improved by using u32 dereferences.
I believe all current uses of is_zero_ether_addr and
is_broadcast_ether_addr are u16 aligned, so always use
u16 references to improve those functions performance.
Document the u16 alignment requirements.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/etherdevice.h')
-rw-r--r-- | include/linux/etherdevice.h | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 2f0e3d0818bc..f344ac04f858 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -61,6 +61,8 @@ static const u8 eth_reserved_addr_base[ETH_ALEN] __aligned(2) = | |||
61 | * | 61 | * |
62 | * Return true if address is link local reserved addr (01:80:c2:00:00:0X) per | 62 | * Return true if address is link local reserved addr (01:80:c2:00:00:0X) per |
63 | * IEEE 802.1Q 8.6.3 Frame filtering. | 63 | * IEEE 802.1Q 8.6.3 Frame filtering. |
64 | * | ||
65 | * Please note: addr must be aligned to u16. | ||
64 | */ | 66 | */ |
65 | static inline bool is_link_local_ether_addr(const u8 *addr) | 67 | static inline bool is_link_local_ether_addr(const u8 *addr) |
66 | { | 68 | { |
@@ -68,7 +70,12 @@ static inline bool is_link_local_ether_addr(const u8 *addr) | |||
68 | static const __be16 *b = (const __be16 *)eth_reserved_addr_base; | 70 | static const __be16 *b = (const __be16 *)eth_reserved_addr_base; |
69 | static const __be16 m = cpu_to_be16(0xfff0); | 71 | static const __be16 m = cpu_to_be16(0xfff0); |
70 | 72 | ||
73 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
74 | return (((*(const u32 *)addr) ^ (*(const u32 *)b)) | | ||
75 | ((a[2] ^ b[2]) & m)) == 0; | ||
76 | #else | ||
71 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; | 77 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; |
78 | #endif | ||
72 | } | 79 | } |
73 | 80 | ||
74 | /** | 81 | /** |
@@ -76,10 +83,18 @@ static inline bool is_link_local_ether_addr(const u8 *addr) | |||
76 | * @addr: Pointer to a six-byte array containing the Ethernet address | 83 | * @addr: Pointer to a six-byte array containing the Ethernet address |
77 | * | 84 | * |
78 | * Return true if the address is all zeroes. | 85 | * Return true if the address is all zeroes. |
86 | * | ||
87 | * Please note: addr must be aligned to u16. | ||
79 | */ | 88 | */ |
80 | static inline bool is_zero_ether_addr(const u8 *addr) | 89 | static inline bool is_zero_ether_addr(const u8 *addr) |
81 | { | 90 | { |
82 | return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); | 91 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
92 | return ((*(const u32 *)addr) | (*(const u16 *)(addr + 4))) == 0; | ||
93 | #else | ||
94 | return (*(const u16 *)(addr + 0) | | ||
95 | *(const u16 *)(addr + 2) | | ||
96 | *(const u16 *)(addr + 4)) == 0; | ||
97 | #endif | ||
83 | } | 98 | } |
84 | 99 | ||
85 | /** | 100 | /** |
@@ -110,10 +125,14 @@ static inline bool is_local_ether_addr(const u8 *addr) | |||
110 | * @addr: Pointer to a six-byte array containing the Ethernet address | 125 | * @addr: Pointer to a six-byte array containing the Ethernet address |
111 | * | 126 | * |
112 | * Return true if the address is the broadcast address. | 127 | * Return true if the address is the broadcast address. |
128 | * | ||
129 | * Please note: addr must be aligned to u16. | ||
113 | */ | 130 | */ |
114 | static inline bool is_broadcast_ether_addr(const u8 *addr) | 131 | static inline bool is_broadcast_ether_addr(const u8 *addr) |
115 | { | 132 | { |
116 | return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; | 133 | return (*(const u16 *)(addr + 0) & |
134 | *(const u16 *)(addr + 2) & | ||
135 | *(const u16 *)(addr + 4)) == 0xffff; | ||
117 | } | 136 | } |
118 | 137 | ||
119 | /** | 138 | /** |
@@ -135,6 +154,8 @@ static inline bool is_unicast_ether_addr(const u8 *addr) | |||
135 | * a multicast address, and is not FF:FF:FF:FF:FF:FF. | 154 | * a multicast address, and is not FF:FF:FF:FF:FF:FF. |
136 | * | 155 | * |
137 | * Return true if the address is valid. | 156 | * Return true if the address is valid. |
157 | * | ||
158 | * Please note: addr must be aligned to u16. | ||
138 | */ | 159 | */ |
139 | static inline bool is_valid_ether_addr(const u8 *addr) | 160 | static inline bool is_valid_ether_addr(const u8 *addr) |
140 | { | 161 | { |