-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fast_hash: avoid indirect function calls
By default the arch_fast_hash hashing function pointers are initialized to jhash(2). If during boot-up a CPU with SSE4.2 is detected they get updated to the CRC32 ones. This dispatching scheme incurs a function pointer lookup and indirect call for every hashing operation. rhashtable as a user of arch_fast_hash e.g. stores pointers to hashing functions in its structure, too, causing two indirect branches per hashing operation. Using alternative_call we can get away with one of those indirect branches. Acked-by: Daniel Borkmann <dborkman@redhat.com> Cc: Thomas Graf <tgraf@suug.ch> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Hannes Frederic Sowa
authored and
David S. Miller
committed
Nov 6, 2014
1 parent
2c99cd9
commit e5a2c89
Showing
6 changed files
with
98 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,48 @@ | ||
#ifndef _ASM_X86_HASH_H | ||
#define _ASM_X86_HASH_H | ||
#ifndef __ASM_X86_HASH_H | ||
#define __ASM_X86_HASH_H | ||
|
||
struct fast_hash_ops; | ||
extern void setup_arch_fast_hash(struct fast_hash_ops *ops); | ||
#include <linux/cpufeature.h> | ||
#include <asm/alternative.h> | ||
|
||
#endif /* _ASM_X86_HASH_H */ | ||
u32 __intel_crc4_2_hash(const void *data, u32 len, u32 seed); | ||
u32 __intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed); | ||
|
||
/* | ||
* non-inline versions of jhash so gcc does not need to generate | ||
* duplicate code in every object file | ||
*/ | ||
u32 __jhash(const void *data, u32 len, u32 seed); | ||
u32 __jhash2(const u32 *data, u32 len, u32 seed); | ||
|
||
/* | ||
* for documentation of these functions please look into | ||
* <include/asm-generic/hash.h> | ||
*/ | ||
|
||
static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed) | ||
{ | ||
u32 hash; | ||
|
||
alternative_call(__jhash, __intel_crc4_2_hash, X86_FEATURE_XMM4_2, | ||
#ifdef CONFIG_X86_64 | ||
"=a" (hash), "D" (data), "S" (len), "d" (seed)); | ||
#else | ||
"=a" (hash), "a" (data), "d" (len), "c" (seed)); | ||
#endif | ||
return hash; | ||
} | ||
|
||
static inline u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed) | ||
{ | ||
u32 hash; | ||
|
||
alternative_call(__jhash2, __intel_crc4_2_hash2, X86_FEATURE_XMM4_2, | ||
#ifdef CONFIG_X86_64 | ||
"=a" (hash), "D" (data), "S" (len), "d" (seed)); | ||
#else | ||
"=a" (hash), "a" (data), "d" (len), "c" (seed)); | ||
#endif | ||
return hash; | ||
} | ||
|
||
#endif /* __ASM_X86_HASH_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,41 @@ | ||
#ifndef __ASM_GENERIC_HASH_H | ||
#define __ASM_GENERIC_HASH_H | ||
|
||
struct fast_hash_ops; | ||
static inline void setup_arch_fast_hash(struct fast_hash_ops *ops) | ||
#include <linux/jhash.h> | ||
|
||
/** | ||
* arch_fast_hash - Caclulates a hash over a given buffer that can have | ||
* arbitrary size. This function will eventually use an | ||
* architecture-optimized hashing implementation if | ||
* available, and trades off distribution for speed. | ||
* | ||
* @data: buffer to hash | ||
* @len: length of buffer in bytes | ||
* @seed: start seed | ||
* | ||
* Returns 32bit hash. | ||
*/ | ||
static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed) | ||
{ | ||
return jhash(data, len, seed); | ||
} | ||
|
||
/** | ||
* arch_fast_hash2 - Caclulates a hash over a given buffer that has a | ||
* size that is of a multiple of 32bit words. This | ||
* function will eventually use an architecture- | ||
* optimized hashing implementation if available, | ||
* and trades off distribution for speed. | ||
* | ||
* @data: buffer to hash (must be 32bit padded) | ||
* @len: number of 32bit words | ||
* @seed: start seed | ||
* | ||
* Returns 32bit hash. | ||
*/ | ||
static inline u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed) | ||
{ | ||
return jhash2(data, len, seed); | ||
} | ||
|
||
#endif /* __ASM_GENERIC_HASH_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.