summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Zumbiehl <florz@florz.de>2007-07-31 13:47:57 -0700
committerDavid S. Miller <davem@davemloft.net>2007-07-31 13:47:57 -0700
commitf1543f8b8316f49b318ac6cd8c78a7fd18509311 (patch)
tree50506ab3d7057e9de2e65bf726ad48043cfbfc45
parent48b8d78315bf2aef4b6b4fb41c2c94e0b6600234 (diff)
downloadlinux-f1543f8b8316f49b318ac6cd8c78a7fd18509311.tar.bz2
[PPPOE]: Improve hashing function in hash_item().
The new code produces the same results as the old version and is ~ 3 to 6 times faster for 4-bit hashes on the CPUs I tested. Signed-off-by: Florian Zumbiehl <florz@florz.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/pppoe.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 35a7385ccb2a..68631a5721ac 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -108,19 +108,24 @@ static inline int cmp_addr(struct pppoe_addr *a, unsigned long sid, char *addr)
(memcmp(a->remote,addr,ETH_ALEN) == 0));
}
-static int hash_item(unsigned long sid, unsigned char *addr)
+#if 8%PPPOE_HASH_BITS
+#error 8 must be a multiple of PPPOE_HASH_BITS
+#endif
+
+static int hash_item(unsigned int sid, unsigned char *addr)
{
- char hash = 0;
- int i, j;
+ unsigned char hash = 0;
+ unsigned int i;
- for (i = 0; i < ETH_ALEN ; ++i) {
- for (j = 0; j < 8/PPPOE_HASH_BITS ; ++j) {
- hash ^= addr[i] >> ( j * PPPOE_HASH_BITS );
- }
+ for (i = 0 ; i < ETH_ALEN ; i++) {
+ hash ^= addr[i];
+ }
+ for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){
+ hash ^= sid>>i;
+ }
+ for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) {
+ hash ^= hash>>i;
}
-
- for (i = 0; i < (sizeof(unsigned long)*8) / PPPOE_HASH_BITS ; ++i)
- hash ^= sid >> (i*PPPOE_HASH_BITS);
return hash & ( PPPOE_HASH_SIZE - 1 );
}