summaryrefslogtreecommitdiff
path: root/include/linux/rhashtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/rhashtable.h')
-rw-r--r--include/linux/rhashtable.h39
1 files changed, 22 insertions, 17 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 57a2a29bef0e..70dac9214617 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -319,18 +319,6 @@ static inline struct rhash_lock_head __rcu **rht_bucket_insert(
* When we write to a bucket without unlocking, we use rht_assign_locked().
*/
-static inline unsigned long rht_lock(struct bucket_table *tbl,
- struct rhash_lock_head __rcu **bkt)
- __acquires(__bitlock(0, bkt))
-{
- unsigned long flags;
-
- local_irq_save(flags);
- bit_spin_lock(0, (unsigned long *)bkt);
- lock_map_acquire(&tbl->dep_map);
- return flags;
-}
-
static inline unsigned long rht_lock_nested(struct bucket_table *tbl,
struct rhash_lock_head __rcu **bucket,
unsigned int subclass)
@@ -344,6 +332,13 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl,
return flags;
}
+static inline unsigned long rht_lock(struct bucket_table *tbl,
+ struct rhash_lock_head __rcu **bkt)
+ __acquires(__bitlock(0, bkt))
+{
+ return rht_lock_nested(tbl, bkt, 0);
+}
+
static inline void rht_unlock(struct bucket_table *tbl,
struct rhash_lock_head __rcu **bkt,
unsigned long flags)
@@ -598,13 +593,23 @@ static inline void rht_assign_unlock(struct bucket_table *tbl,
for (pos = list; pos && rht_entry(tpos, pos, member); \
pos = rcu_dereference_all(pos->next))
-static inline int rhashtable_compare(struct rhashtable_compare_arg *arg,
- const void *obj)
+/*
+ * Use constant params from inlined callers to specialize memcmp(). If params
+ * isn't constant, it must be equal to ht->p.
+ */
+static __always_inline int rhashtable_compare(struct rhashtable_compare_arg *arg,
+ const void *obj,
+ const struct rhashtable_params params)
{
struct rhashtable *ht = arg->ht;
const char *ptr = obj;
- return memcmp(ptr + ht->p.key_offset, arg->key, ht->p.key_len);
+ if (!__builtin_constant_p(params.key_len))
+ return memcmp(ptr + ht->p.key_offset, arg->key,
+ ht->p.key_len);
+
+ return memcmp(ptr + params.key_offset, arg->key,
+ params.key_len ? : ht->p.key_len);
}
/* Internal function, do not use. */
@@ -632,7 +637,7 @@ restart:
rht_for_each_rcu_from(he, __rht_ptr_rcu(bkt, freq), tbl, hash) {
if (params.obj_cmpfn ?
params.obj_cmpfn(&arg, rht_obj(ht, he)) :
- rhashtable_compare(&arg, rht_obj(ht, he)))
+ rhashtable_compare(&arg, rht_obj(ht, he), params))
continue;
return he;
}
@@ -797,7 +802,7 @@ slow_path:
if (!key ||
(params.obj_cmpfn ?
params.obj_cmpfn(&arg, rht_obj(ht, head)) :
- rhashtable_compare(&arg, rht_obj(ht, head)))) {
+ rhashtable_compare(&arg, rht_obj(ht, head), params))) {
pprev = &head->next;
continue;
}