OSDN Git Service

rhashtable: Add rhashtable_lookup()
authorBen Hutchings <ben.hutchings@codethink.co.uk>
Fri, 7 Dec 2018 17:16:46 +0000 (17:16 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Feb 2019 10:25:30 +0000 (11:25 +0100)
Extracted from commit ca26893f05e8 "rhashtable: Add rhlist interface".

Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/rhashtable.h

index e07eca0..753835d 100644 (file)
@@ -515,18 +515,8 @@ static inline int rhashtable_compare(struct rhashtable_compare_arg *arg,
        return memcmp(ptr + ht->p.key_offset, arg->key, ht->p.key_len);
 }
 
-/**
- * rhashtable_lookup_fast - search hash table, inlined version
- * @ht:                hash table
- * @key:       the pointer to the key
- * @params:    hash table parameters
- *
- * Computes the hash value for the key and traverses the bucket chain looking
- * for a entry with an identical key. The first matching entry is returned.
- *
- * Returns the first entry on which the compare function returned true.
- */
-static inline void *rhashtable_lookup_fast(
+/* Internal function, do not use. */
+static inline struct rhash_head *__rhashtable_lookup(
        struct rhashtable *ht, const void *key,
        const struct rhashtable_params params)
 {
@@ -538,8 +528,6 @@ static inline void *rhashtable_lookup_fast(
        struct rhash_head *he;
        unsigned int hash;
 
-       rcu_read_lock();
-
        tbl = rht_dereference_rcu(ht->tbl, ht);
 restart:
        hash = rht_key_hashfn(ht, tbl, key, params);
@@ -548,8 +536,7 @@ restart:
                    params.obj_cmpfn(&arg, rht_obj(ht, he)) :
                    rhashtable_compare(&arg, rht_obj(ht, he)))
                        continue;
-               rcu_read_unlock();
-               return rht_obj(ht, he);
+               return he;
        }
 
        /* Ensure we see any new tables. */
@@ -558,11 +545,59 @@ restart:
        tbl = rht_dereference_rcu(tbl->future_tbl, ht);
        if (unlikely(tbl))
                goto restart;
-       rcu_read_unlock();
 
        return NULL;
 }
 
+/**
+ * rhashtable_lookup - search hash table
+ * @ht:                hash table
+ * @key:       the pointer to the key
+ * @params:    hash table parameters
+ *
+ * Computes the hash value for the key and traverses the bucket chain looking
+ * for a entry with an identical key. The first matching entry is returned.
+ *
+ * This must only be called under the RCU read lock.
+ *
+ * Returns the first entry on which the compare function returned true.
+ */
+static inline void *rhashtable_lookup(
+       struct rhashtable *ht, const void *key,
+       const struct rhashtable_params params)
+{
+       struct rhash_head *he = __rhashtable_lookup(ht, key, params);
+
+       return he ? rht_obj(ht, he) : NULL;
+}
+
+/**
+ * rhashtable_lookup_fast - search hash table, without RCU read lock
+ * @ht:                hash table
+ * @key:       the pointer to the key
+ * @params:    hash table parameters
+ *
+ * Computes the hash value for the key and traverses the bucket chain looking
+ * for a entry with an identical key. The first matching entry is returned.
+ *
+ * Only use this function when you have other mechanisms guaranteeing
+ * that the object won't go away after the RCU read lock is released.
+ *
+ * Returns the first entry on which the compare function returned true.
+ */
+static inline void *rhashtable_lookup_fast(
+       struct rhashtable *ht, const void *key,
+       const struct rhashtable_params params)
+{
+       void *obj;
+
+       rcu_read_lock();
+       obj = rhashtable_lookup(ht, key, params);
+       rcu_read_unlock();
+
+       return obj;
+}
+
 /* Internal function, please use rhashtable_insert_fast() instead. This
  * function returns the existing element already in hashes in there is a clash,
  * otherwise it returns an error via ERR_PTR().