diff options
author | Joe Perches <joe@perches.com> | 2013-12-05 17:54:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-06 16:37:43 -0500 |
commit | 0d74c42f788caf3cad727c61c490d9459bc8918b (patch) | |
tree | 6eaff61e95e9efd14e85d2c8bb159ec5ff3b2898 /Documentation/unaligned-memory-access.txt | |
parent | 5cc208becb10ca271d8a3299a09a5449490c7591 (diff) |
ether_addr_equal: Optimize implementation, remove unused compare_ether_addr
Add a new check for CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS to reduce
the number of or's used in the ether_addr_equal comparison to very
slightly improve function performance.
Simplify the ether_addr_equal_64bits implementation.
Integrate and remove the zap_last_2bytes helper as it's now
used only once.
Remove the now unused compare_ether_addr function.
Update the unaligned-memory-access documentation to remove the
compare_ether_addr description and show how unaligned accesses
could occur with ether_addr_equal.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'Documentation/unaligned-memory-access.txt')
-rw-r--r-- | Documentation/unaligned-memory-access.txt | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/Documentation/unaligned-memory-access.txt b/Documentation/unaligned-memory-access.txt index f866c72291bf..a445da098bc6 100644 --- a/Documentation/unaligned-memory-access.txt +++ b/Documentation/unaligned-memory-access.txt | |||
@@ -137,24 +137,34 @@ Code that causes unaligned access | |||
137 | ================================= | 137 | ================================= |
138 | 138 | ||
139 | With the above in mind, let's move onto a real life example of a function | 139 | With the above in mind, let's move onto a real life example of a function |
140 | that can cause an unaligned memory access. The following function adapted | 140 | that can cause an unaligned memory access. The following function taken |
141 | from include/linux/etherdevice.h is an optimized routine to compare two | 141 | from include/linux/etherdevice.h is an optimized routine to compare two |
142 | ethernet MAC addresses for equality. | 142 | ethernet MAC addresses for equality. |
143 | 143 | ||
144 | unsigned int compare_ether_addr(const u8 *addr1, const u8 *addr2) | 144 | bool ether_addr_equal(const u8 *addr1, const u8 *addr2) |
145 | { | 145 | { |
146 | const u16 *a = (const u16 *) addr1; | 146 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS |
147 | const u16 *b = (const u16 *) addr2; | 147 | u32 fold = ((*(const u32 *)addr1) ^ (*(const u32 *)addr2)) | |
148 | ((*(const u16 *)(addr1 + 4)) ^ (*(const u16 *)(addr2 + 4))); | ||
149 | |||
150 | return fold == 0; | ||
151 | #else | ||
152 | const u16 *a = (const u16 *)addr1; | ||
153 | const u16 *b = (const u16 *)addr2; | ||
148 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; | 154 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; |
155 | #endif | ||
149 | } | 156 | } |
150 | 157 | ||
151 | In the above function, the reference to a[0] causes 2 bytes (16 bits) to | 158 | In the above function, when the hardware has efficient unaligned access |
152 | be read from memory starting at address addr1. Think about what would happen | 159 | capability, there is no issue with this code. But when the hardware isn't |
153 | if addr1 was an odd address such as 0x10003. (Hint: it'd be an unaligned | 160 | able to access memory on arbitrary boundaries, the reference to a[0] causes |
154 | access.) | 161 | 2 bytes (16 bits) to be read from memory starting at address addr1. |
162 | |||
163 | Think about what would happen if addr1 was an odd address such as 0x10003. | ||
164 | (Hint: it'd be an unaligned access.) | ||
155 | 165 | ||
156 | Despite the potential unaligned access problems with the above function, it | 166 | Despite the potential unaligned access problems with the above function, it |
157 | is included in the kernel anyway but is understood to only work on | 167 | is included in the kernel anyway but is understood to only work normally on |
158 | 16-bit-aligned addresses. It is up to the caller to ensure this alignment or | 168 | 16-bit-aligned addresses. It is up to the caller to ensure this alignment or |
159 | not use this function at all. This alignment-unsafe function is still useful | 169 | not use this function at all. This alignment-unsafe function is still useful |
160 | as it is a decent optimization for the cases when you can ensure alignment, | 170 | as it is a decent optimization for the cases when you can ensure alignment, |