diff options
| author | David S. Miller <davem@davemloft.net> | 2017-12-11 09:58:39 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-12-11 09:58:39 -0500 |
| commit | 9944a0f2f502e4501fccb1dc0a64a6012c83dd97 (patch) | |
| tree | 98769c3324dd57bc2070c08852c9bf1f272ba2b8 /include/linux/rhashtable.h | |
| parent | a0b586fa75a69578ecf10b40582eed9b35de2432 (diff) | |
| parent | 64e0cd0d3540dbbdf6661943025409e6b31d5178 (diff) | |
Merge branch 'rhashtable-New-features-in-walk-and-bucket'
Tom Herbert says:
====================
rhashtable: New features in walk and bucket
This patch contains some changes to related rhashtable:
- Above allow rhashtable_walk_start to return void
- Add a functon to peek at the next entry during a walk
- Abstract out function to compute a has for a table
- A library function to alloc a spinlocks bucket array
- Call the above function for rhashtable locks allocation
Tested: Exercised using various operations on an ILA xlat
table.
v2:
- Apply feedback from Herbert. Don't change semantics of resize
event reporting and -EAGAIN, just simplify API for callers that
ignore those.
- Add end_of_table in iter to reliably tell when the iterator has
reached to the eno.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/rhashtable.h')
| -rw-r--r-- | include/linux/rhashtable.h | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 361c08e35dbc..c9df2527e0cd 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h | |||
| @@ -207,6 +207,7 @@ struct rhashtable_iter { | |||
| 207 | struct rhashtable_walker walker; | 207 | struct rhashtable_walker walker; |
| 208 | unsigned int slot; | 208 | unsigned int slot; |
| 209 | unsigned int skip; | 209 | unsigned int skip; |
| 210 | bool end_of_table; | ||
| 210 | }; | 211 | }; |
| 211 | 212 | ||
| 212 | static inline unsigned long rht_marker(const struct rhashtable *ht, u32 hash) | 213 | static inline unsigned long rht_marker(const struct rhashtable *ht, u32 hash) |
| @@ -239,34 +240,42 @@ static inline unsigned int rht_bucket_index(const struct bucket_table *tbl, | |||
| 239 | return (hash >> RHT_HASH_RESERVED_SPACE) & (tbl->size - 1); | 240 | return (hash >> RHT_HASH_RESERVED_SPACE) & (tbl->size - 1); |
| 240 | } | 241 | } |
| 241 | 242 | ||
| 242 | static inline unsigned int rht_key_hashfn( | 243 | static inline unsigned int rht_key_get_hash(struct rhashtable *ht, |
| 243 | struct rhashtable *ht, const struct bucket_table *tbl, | 244 | const void *key, const struct rhashtable_params params, |
| 244 | const void *key, const struct rhashtable_params params) | 245 | unsigned int hash_rnd) |
| 245 | { | 246 | { |
| 246 | unsigned int hash; | 247 | unsigned int hash; |
| 247 | 248 | ||
| 248 | /* params must be equal to ht->p if it isn't constant. */ | 249 | /* params must be equal to ht->p if it isn't constant. */ |
| 249 | if (!__builtin_constant_p(params.key_len)) | 250 | if (!__builtin_constant_p(params.key_len)) |
| 250 | hash = ht->p.hashfn(key, ht->key_len, tbl->hash_rnd); | 251 | hash = ht->p.hashfn(key, ht->key_len, hash_rnd); |
| 251 | else if (params.key_len) { | 252 | else if (params.key_len) { |
| 252 | unsigned int key_len = params.key_len; | 253 | unsigned int key_len = params.key_len; |
| 253 | 254 | ||
| 254 | if (params.hashfn) | 255 | if (params.hashfn) |
| 255 | hash = params.hashfn(key, key_len, tbl->hash_rnd); | 256 | hash = params.hashfn(key, key_len, hash_rnd); |
| 256 | else if (key_len & (sizeof(u32) - 1)) | 257 | else if (key_len & (sizeof(u32) - 1)) |
| 257 | hash = jhash(key, key_len, tbl->hash_rnd); | 258 | hash = jhash(key, key_len, hash_rnd); |
| 258 | else | 259 | else |
| 259 | hash = jhash2(key, key_len / sizeof(u32), | 260 | hash = jhash2(key, key_len / sizeof(u32), hash_rnd); |
| 260 | tbl->hash_rnd); | ||
| 261 | } else { | 261 | } else { |
| 262 | unsigned int key_len = ht->p.key_len; | 262 | unsigned int key_len = ht->p.key_len; |
| 263 | 263 | ||
| 264 | if (params.hashfn) | 264 | if (params.hashfn) |
| 265 | hash = params.hashfn(key, key_len, tbl->hash_rnd); | 265 | hash = params.hashfn(key, key_len, hash_rnd); |
| 266 | else | 266 | else |
| 267 | hash = jhash(key, key_len, tbl->hash_rnd); | 267 | hash = jhash(key, key_len, hash_rnd); |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | return hash; | ||
| 271 | } | ||
| 272 | |||
| 273 | static inline unsigned int rht_key_hashfn( | ||
| 274 | struct rhashtable *ht, const struct bucket_table *tbl, | ||
| 275 | const void *key, const struct rhashtable_params params) | ||
| 276 | { | ||
| 277 | unsigned int hash = rht_key_get_hash(ht, key, params, tbl->hash_rnd); | ||
| 278 | |||
| 270 | return rht_bucket_index(tbl, hash); | 279 | return rht_bucket_index(tbl, hash); |
| 271 | } | 280 | } |
| 272 | 281 | ||
| @@ -378,8 +387,15 @@ void *rhashtable_insert_slow(struct rhashtable *ht, const void *key, | |||
| 378 | void rhashtable_walk_enter(struct rhashtable *ht, | 387 | void rhashtable_walk_enter(struct rhashtable *ht, |
| 379 | struct rhashtable_iter *iter); | 388 | struct rhashtable_iter *iter); |
| 380 | void rhashtable_walk_exit(struct rhashtable_iter *iter); | 389 | void rhashtable_walk_exit(struct rhashtable_iter *iter); |
| 381 | int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU); | 390 | int rhashtable_walk_start_check(struct rhashtable_iter *iter) __acquires(RCU); |
| 391 | |||
| 392 | static inline void rhashtable_walk_start(struct rhashtable_iter *iter) | ||
| 393 | { | ||
| 394 | (void)rhashtable_walk_start_check(iter); | ||
| 395 | } | ||
| 396 | |||
| 382 | void *rhashtable_walk_next(struct rhashtable_iter *iter); | 397 | void *rhashtable_walk_next(struct rhashtable_iter *iter); |
| 398 | void *rhashtable_walk_peek(struct rhashtable_iter *iter); | ||
| 383 | void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU); | 399 | void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU); |
| 384 | 400 | ||
| 385 | void rhashtable_free_and_destroy(struct rhashtable *ht, | 401 | void rhashtable_free_and_destroy(struct rhashtable *ht, |
