diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 12:27:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 12:27:32 -0700 |
commit | d9fcca40eba3266c1c8b6d9d7ab163861ad23b66 (patch) | |
tree | 7d69afe258fa57a844b293b4c84c8369ae15b15a /arch | |
parent | 7cc3afdf43ffb703db831292f3816d909fd44767 (diff) | |
parent | 7a5917e9787dd73284f04e35c3cfdb39a67bf0d5 (diff) | |
download | linux-d9fcca40eba3266c1c8b6d9d7ab163861ad23b66.tar.bz2 |
Merge branch 'x86-hash-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 hashing changes from Ingo Molnar:
"Small fixes and cleanups to the librarized arch_fast_hash() methods,
used by the net/openvswitch code"
* 'x86-hash-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, hash: Simplify switch, add __init annotation
x86, hash: Swap arguments passed to crc32_u32()
x86, hash: Fix build failure with older binutils
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/hash.c | 22 |
2 files changed, 14 insertions, 9 deletions
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index a414b1471ffc..3b9348a0c1a4 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -152,6 +152,7 @@ cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTI # does binutils support specific instructions? asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1) +asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1) avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1) avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1) diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index 3056702e81fb..ff4fa51a5b1f 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -32,6 +32,7 @@ */ #include <linux/hash.h> +#include <linux/init.h> #include <asm/processor.h> #include <asm/cpufeature.h> @@ -39,7 +40,11 @@ static inline u32 crc32_u32(u32 crc, u32 val) { +#ifdef CONFIG_AS_CRC32 asm ("crc32l %1,%0\n" : "+r" (crc) : "rm" (val)); +#else + asm (".byte 0xf2, 0x0f, 0x38, 0xf1, 0xc1" : "+a" (crc) : "c" (val)); +#endif return crc; } @@ -49,19 +54,18 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) u32 i, tmp = 0; for (i = 0; i < len / 4; i++) - seed = crc32_u32(*p32++, seed); + seed = crc32_u32(seed, *p32++); - switch (3 - (len & 0x03)) { - case 0: + switch (len & 3) { + case 3: tmp |= *((const u8 *) p32 + 2) << 16; /* fallthrough */ - case 1: + case 2: tmp |= *((const u8 *) p32 + 1) << 8; /* fallthrough */ - case 2: + case 1: tmp |= *((const u8 *) p32); - seed = crc32_u32(tmp, seed); - default: + seed = crc32_u32(seed, tmp); break; } @@ -74,12 +78,12 @@ static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) u32 i; for (i = 0; i < len; i++) - seed = crc32_u32(*p32++, seed); + seed = crc32_u32(seed, *p32++); return seed; } -void setup_arch_fast_hash(struct fast_hash_ops *ops) +void __init setup_arch_fast_hash(struct fast_hash_ops *ops) { if (cpu_has_xmm4_2) { ops->hash = intel_crc4_2_hash; |