diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2015-03-09 18:27:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-11 16:28:25 -0400 |
commit | 988dfbd795cf08b00576c1ced4210281b2bccffc (patch) | |
tree | 535e1fbd7224c49386a5de1a8afc16948078489e /lib/rhashtable.c | |
parent | 0ddcf43d5d4a03ded1ee3f6b3b72a0cbed4e90b1 (diff) |
rhashtable: Move hash_rnd into bucket_table
Currently hash_rnd is a parameter that users can set. However,
no existing users set this parameter. It is also something that
people are unlikely to want to set directly since it's just a
random number.
In preparation for allowing the reseeding/rehashing of rhashtable,
this patch moves hash_rnd into bucket_table so that it's now an
internal state rather than a parameter.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib/rhashtable.c')
-rw-r--r-- | lib/rhashtable.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index b5344ef4c684..ba15dceee27f 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -66,25 +66,28 @@ static u32 rht_bucket_index(const struct bucket_table *tbl, u32 hash) | |||
66 | return hash & (tbl->size - 1); | 66 | return hash & (tbl->size - 1); |
67 | } | 67 | } |
68 | 68 | ||
69 | static u32 obj_raw_hashfn(const struct rhashtable *ht, const void *ptr) | 69 | static u32 obj_raw_hashfn(struct rhashtable *ht, const void *ptr) |
70 | { | 70 | { |
71 | struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht); | ||
71 | u32 hash; | 72 | u32 hash; |
72 | 73 | ||
73 | if (unlikely(!ht->p.key_len)) | 74 | if (unlikely(!ht->p.key_len)) |
74 | hash = ht->p.obj_hashfn(ptr, ht->p.hash_rnd); | 75 | hash = ht->p.obj_hashfn(ptr, tbl->hash_rnd); |
75 | else | 76 | else |
76 | hash = ht->p.hashfn(ptr + ht->p.key_offset, ht->p.key_len, | 77 | hash = ht->p.hashfn(ptr + ht->p.key_offset, ht->p.key_len, |
77 | ht->p.hash_rnd); | 78 | tbl->hash_rnd); |
78 | 79 | ||
79 | return hash >> HASH_RESERVED_SPACE; | 80 | return hash >> HASH_RESERVED_SPACE; |
80 | } | 81 | } |
81 | 82 | ||
82 | static u32 key_hashfn(struct rhashtable *ht, const void *key, u32 len) | 83 | static u32 key_hashfn(struct rhashtable *ht, const void *key, u32 len) |
83 | { | 84 | { |
84 | return ht->p.hashfn(key, len, ht->p.hash_rnd) >> HASH_RESERVED_SPACE; | 85 | struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht); |
86 | |||
87 | return ht->p.hashfn(key, len, tbl->hash_rnd) >> HASH_RESERVED_SPACE; | ||
85 | } | 88 | } |
86 | 89 | ||
87 | static u32 head_hashfn(const struct rhashtable *ht, | 90 | static u32 head_hashfn(struct rhashtable *ht, |
88 | const struct bucket_table *tbl, | 91 | const struct bucket_table *tbl, |
89 | const struct rhash_head *he) | 92 | const struct rhash_head *he) |
90 | { | 93 | { |
@@ -92,7 +95,7 @@ static u32 head_hashfn(const struct rhashtable *ht, | |||
92 | } | 95 | } |
93 | 96 | ||
94 | #ifdef CONFIG_PROVE_LOCKING | 97 | #ifdef CONFIG_PROVE_LOCKING |
95 | static void debug_dump_buckets(const struct rhashtable *ht, | 98 | static void debug_dump_buckets(struct rhashtable *ht, |
96 | const struct bucket_table *tbl) | 99 | const struct bucket_table *tbl) |
97 | { | 100 | { |
98 | struct rhash_head *he; | 101 | struct rhash_head *he; |
@@ -385,6 +388,8 @@ int rhashtable_expand(struct rhashtable *ht) | |||
385 | if (new_tbl == NULL) | 388 | if (new_tbl == NULL) |
386 | return -ENOMEM; | 389 | return -ENOMEM; |
387 | 390 | ||
391 | new_tbl->hash_rnd = old_tbl->hash_rnd; | ||
392 | |||
388 | atomic_inc(&ht->shift); | 393 | atomic_inc(&ht->shift); |
389 | 394 | ||
390 | /* Make insertions go into the new, empty table right away. Deletions | 395 | /* Make insertions go into the new, empty table right away. Deletions |
@@ -476,6 +481,8 @@ int rhashtable_shrink(struct rhashtable *ht) | |||
476 | if (new_tbl == NULL) | 481 | if (new_tbl == NULL) |
477 | return -ENOMEM; | 482 | return -ENOMEM; |
478 | 483 | ||
484 | new_tbl->hash_rnd = tbl->hash_rnd; | ||
485 | |||
479 | rcu_assign_pointer(ht->future_tbl, new_tbl); | 486 | rcu_assign_pointer(ht->future_tbl, new_tbl); |
480 | synchronize_rcu(); | 487 | synchronize_rcu(); |
481 | 488 | ||
@@ -1099,14 +1106,13 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params) | |||
1099 | if (tbl == NULL) | 1106 | if (tbl == NULL) |
1100 | return -ENOMEM; | 1107 | return -ENOMEM; |
1101 | 1108 | ||
1109 | get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); | ||
1110 | |||
1102 | atomic_set(&ht->nelems, 0); | 1111 | atomic_set(&ht->nelems, 0); |
1103 | atomic_set(&ht->shift, ilog2(tbl->size)); | 1112 | atomic_set(&ht->shift, ilog2(tbl->size)); |
1104 | RCU_INIT_POINTER(ht->tbl, tbl); | 1113 | RCU_INIT_POINTER(ht->tbl, tbl); |
1105 | RCU_INIT_POINTER(ht->future_tbl, tbl); | 1114 | RCU_INIT_POINTER(ht->future_tbl, tbl); |
1106 | 1115 | ||
1107 | if (!ht->p.hash_rnd) | ||
1108 | get_random_bytes(&ht->p.hash_rnd, sizeof(ht->p.hash_rnd)); | ||
1109 | |||
1110 | INIT_WORK(&ht->run_work, rht_deferred_worker); | 1116 | INIT_WORK(&ht->run_work, rht_deferred_worker); |
1111 | 1117 | ||
1112 | return 0; | 1118 | return 0; |