Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/rhashtable.h
1307 views
/*1* Resizable, Scalable, Concurrent Hash Table2*3* Copyright (c) 2015 Herbert Xu <[email protected]>4* Copyright (c) 2014-2015 Thomas Graf <[email protected]>5* Copyright (c) 2008-2014 Patrick McHardy <[email protected]>6*7* Code partially derived from nft_hash8* Rewritten with rehash code from br_multicast plus single list9* pointer as suggested by Josh Triplett10*11* This program is free software; you can redistribute it and/or modify12* it under the terms of the GNU General Public License version 2 as13* published by the Free Software Foundation.14*/1516#ifndef _LINUX_RHASHTABLE_H17#define _LINUX_RHASHTABLE_H1819#include <linux/atomic.h>20#include <linux/compiler.h>21#include <linux/err.h>22#include <linux/errno.h>23#include <linux/jhash.h>24#include <linux/list_nulls.h>25#include <linux/workqueue.h>26#include <linux/mutex.h>27#include <linux/rcupdate.h>2829/*30* The end of the chain is marked with a special nulls marks which has31* the following format:32*33* +-------+-----------------------------------------------------+-+34* | Base | Hash |1|35* +-------+-----------------------------------------------------+-+36*37* Base (4 bits) : Reserved to distinguish between multiple tables.38* Specified via &struct rhashtable_params.nulls_base.39* Hash (27 bits): Full hash (unmasked) of first element added to bucket40* 1 (1 bit) : Nulls marker (always set)41*42* The remaining bits of the next pointer remain unused for now.43*/44#define RHT_BASE_BITS 445#define RHT_HASH_BITS 2746#define RHT_BASE_SHIFT RHT_HASH_BITS4748/* Base bits plus 1 bit for nulls marker */49#define RHT_HASH_RESERVED_SPACE (RHT_BASE_BITS + 1)5051struct rhash_head {52struct rhash_head __rcu *next;53};5455/**56* struct bucket_table - Table of hash buckets57* @size: Number of hash buckets58* @rehash: Current bucket being rehashed59* @hash_rnd: Random seed to fold into hash60* @locks_mask: Mask to apply before accessing locks[]61* @locks: Array of spinlocks protecting individual buckets62* @walkers: List of active walkers63* @rcu: RCU structure for freeing the table64* @future_tbl: Table under construction during rehashing65* @buckets: size * hash buckets66*/67struct bucket_table {68unsigned int size;69unsigned int rehash;70u32 hash_rnd;71unsigned int locks_mask;72spinlock_t *locks;73struct list_head walkers;74struct rcu_head rcu;7576struct bucket_table __rcu *future_tbl;7778struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp;79};8081/**82* struct rhashtable_compare_arg - Key for the function rhashtable_compare83* @ht: Hash table84* @key: Key to compare against85*/86struct rhashtable_compare_arg {87struct rhashtable *ht;88const void *key;89};9091typedef u32 (*rht_hashfn_t)(const void *data, u32 len, u32 seed);92typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 len, u32 seed);93typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,94const void *obj);9596struct rhashtable;9798/**99* struct rhashtable_params - Hash table construction parameters100* @nelem_hint: Hint on number of elements, should be 75% of desired size101* @key_len: Length of key102* @key_offset: Offset of key in struct to be hashed103* @head_offset: Offset of rhash_head in struct to be hashed104* @insecure_max_entries: Maximum number of entries (may be exceeded)105* @max_size: Maximum size while expanding106* @min_size: Minimum size while shrinking107* @nulls_base: Base value to generate nulls marker108* @insecure_elasticity: Set to true to disable chain length checks109* @automatic_shrinking: Enable automatic shrinking of tables110* @locks_mul: Number of bucket locks to allocate per cpu (default: 128)111* @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash)112* @obj_hashfn: Function to hash object113* @obj_cmpfn: Function to compare key with object114*/115struct rhashtable_params {116size_t nelem_hint;117size_t key_len;118size_t key_offset;119size_t head_offset;120unsigned int insecure_max_entries;121unsigned int max_size;122unsigned int min_size;123u32 nulls_base;124bool insecure_elasticity;125bool automatic_shrinking;126size_t locks_mul;127rht_hashfn_t hashfn;128rht_obj_hashfn_t obj_hashfn;129rht_obj_cmpfn_t obj_cmpfn;130};131132/**133* struct rhashtable - Hash table handle134* @tbl: Bucket table135* @nelems: Number of elements in table136* @key_len: Key length for hashfn137* @elasticity: Maximum chain length before rehash138* @p: Configuration parameters139* @run_work: Deferred worker to expand/shrink asynchronously140* @mutex: Mutex to protect current/future table swapping141* @lock: Spin lock to protect walker list142*/143struct rhashtable {144struct bucket_table __rcu *tbl;145atomic_t nelems;146unsigned int key_len;147unsigned int elasticity;148struct rhashtable_params p;149struct work_struct run_work;150struct mutex mutex;151spinlock_t lock;152};153154/**155* struct rhashtable_walker - Hash table walker156* @list: List entry on list of walkers157* @tbl: The table that we were walking over158*/159struct rhashtable_walker {160struct list_head list;161struct bucket_table *tbl;162};163164/**165* struct rhashtable_iter - Hash table iterator, fits into netlink cb166* @ht: Table to iterate through167* @p: Current pointer168* @walker: Associated rhashtable walker169* @slot: Current slot170* @skip: Number of entries to skip in slot171*/172struct rhashtable_iter {173struct rhashtable *ht;174struct rhash_head *p;175struct rhashtable_walker *walker;176unsigned int slot;177unsigned int skip;178};179180static inline unsigned long rht_marker(const struct rhashtable *ht, u32 hash)181{182return NULLS_MARKER(ht->p.nulls_base + hash);183}184185#define INIT_RHT_NULLS_HEAD(ptr, ht, hash) \186((ptr) = (typeof(ptr)) rht_marker(ht, hash))187188static inline bool rht_is_a_nulls(const struct rhash_head *ptr)189{190return ((unsigned long) ptr & 1);191}192193static inline unsigned long rht_get_nulls_value(const struct rhash_head *ptr)194{195return ((unsigned long) ptr) >> 1;196}197198static inline void *rht_obj(const struct rhashtable *ht,199const struct rhash_head *he)200{201return (char *)he - ht->p.head_offset;202}203204static inline unsigned int rht_bucket_index(const struct bucket_table *tbl,205unsigned int hash)206{207return (hash >> RHT_HASH_RESERVED_SPACE) & (tbl->size - 1);208}209210static inline unsigned int rht_key_hashfn(211struct rhashtable *ht, const struct bucket_table *tbl,212const void *key, const struct rhashtable_params params)213{214unsigned int hash;215216/* params must be equal to ht->p if it isn't constant. */217if (!__builtin_constant_p(params.key_len))218hash = ht->p.hashfn(key, ht->key_len, tbl->hash_rnd);219else if (params.key_len) {220unsigned int key_len = params.key_len;221222if (params.hashfn)223hash = params.hashfn(key, key_len, tbl->hash_rnd);224else if (key_len & (sizeof(u32) - 1))225hash = jhash(key, key_len, tbl->hash_rnd);226else227hash = jhash2(key, key_len / sizeof(u32),228tbl->hash_rnd);229} else {230unsigned int key_len = ht->p.key_len;231232if (params.hashfn)233hash = params.hashfn(key, key_len, tbl->hash_rnd);234else235hash = jhash(key, key_len, tbl->hash_rnd);236}237238return rht_bucket_index(tbl, hash);239}240241static inline unsigned int rht_head_hashfn(242struct rhashtable *ht, const struct bucket_table *tbl,243const struct rhash_head *he, const struct rhashtable_params params)244{245const char *ptr = rht_obj(ht, he);246247return likely(params.obj_hashfn) ?248rht_bucket_index(tbl, params.obj_hashfn(ptr, params.key_len ?:249ht->p.key_len,250tbl->hash_rnd)) :251rht_key_hashfn(ht, tbl, ptr + params.key_offset, params);252}253254/**255* rht_grow_above_75 - returns true if nelems > 0.75 * table-size256* @ht: hash table257* @tbl: current table258*/259static inline bool rht_grow_above_75(const struct rhashtable *ht,260const struct bucket_table *tbl)261{262/* Expand table when exceeding 75% load */263return atomic_read(&ht->nelems) > (tbl->size / 4 * 3) &&264(!ht->p.max_size || tbl->size < ht->p.max_size);265}266267/**268* rht_shrink_below_30 - returns true if nelems < 0.3 * table-size269* @ht: hash table270* @tbl: current table271*/272static inline bool rht_shrink_below_30(const struct rhashtable *ht,273const struct bucket_table *tbl)274{275/* Shrink table beneath 30% load */276return atomic_read(&ht->nelems) < (tbl->size * 3 / 10) &&277tbl->size > ht->p.min_size;278}279280/**281* rht_grow_above_100 - returns true if nelems > table-size282* @ht: hash table283* @tbl: current table284*/285static inline bool rht_grow_above_100(const struct rhashtable *ht,286const struct bucket_table *tbl)287{288return atomic_read(&ht->nelems) > tbl->size &&289(!ht->p.max_size || tbl->size < ht->p.max_size);290}291292/**293* rht_grow_above_max - returns true if table is above maximum294* @ht: hash table295* @tbl: current table296*/297static inline bool rht_grow_above_max(const struct rhashtable *ht,298const struct bucket_table *tbl)299{300return ht->p.insecure_max_entries &&301atomic_read(&ht->nelems) >= ht->p.insecure_max_entries;302}303304/* The bucket lock is selected based on the hash and protects mutations305* on a group of hash buckets.306*307* A maximum of tbl->size/2 bucket locks is allocated. This ensures that308* a single lock always covers both buckets which may both contains309* entries which link to the same bucket of the old table during resizing.310* This allows to simplify the locking as locking the bucket in both311* tables during resize always guarantee protection.312*313* IMPORTANT: When holding the bucket lock of both the old and new table314* during expansions and shrinking, the old bucket lock must always be315* acquired first.316*/317static inline spinlock_t *rht_bucket_lock(const struct bucket_table *tbl,318unsigned int hash)319{320return &tbl->locks[hash & tbl->locks_mask];321}322323#ifdef CONFIG_PROVE_LOCKING324int lockdep_rht_mutex_is_held(struct rhashtable *ht);325int lockdep_rht_bucket_is_held(const struct bucket_table *tbl, u32 hash);326#else327static inline int lockdep_rht_mutex_is_held(struct rhashtable *ht)328{329return 1;330}331332static inline int lockdep_rht_bucket_is_held(const struct bucket_table *tbl,333u32 hash)334{335return 1;336}337#endif /* CONFIG_PROVE_LOCKING */338339int rhashtable_init(struct rhashtable *ht,340const struct rhashtable_params *params);341342struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,343const void *key,344struct rhash_head *obj,345struct bucket_table *old_tbl);346int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl);347348int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter);349void rhashtable_walk_exit(struct rhashtable_iter *iter);350int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU);351void *rhashtable_walk_next(struct rhashtable_iter *iter);352void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU);353354void rhashtable_free_and_destroy(struct rhashtable *ht,355void (*free_fn)(void *ptr, void *arg),356void *arg);357void rhashtable_destroy(struct rhashtable *ht);358359#define rht_dereference(p, ht) \360rcu_dereference_protected(p, lockdep_rht_mutex_is_held(ht))361362#define rht_dereference_rcu(p, ht) \363rcu_dereference_check(p, lockdep_rht_mutex_is_held(ht))364365#define rht_dereference_bucket(p, tbl, hash) \366rcu_dereference_protected(p, lockdep_rht_bucket_is_held(tbl, hash))367368#define rht_dereference_bucket_rcu(p, tbl, hash) \369rcu_dereference_check(p, lockdep_rht_bucket_is_held(tbl, hash))370371#define rht_entry(tpos, pos, member) \372({ tpos = container_of(pos, typeof(*tpos), member); 1; })373374/**375* rht_for_each_continue - continue iterating over hash chain376* @pos: the &struct rhash_head to use as a loop cursor.377* @head: the previous &struct rhash_head to continue from378* @tbl: the &struct bucket_table379* @hash: the hash value / bucket index380*/381#define rht_for_each_continue(pos, head, tbl, hash) \382for (pos = rht_dereference_bucket(head, tbl, hash); \383!rht_is_a_nulls(pos); \384pos = rht_dereference_bucket((pos)->next, tbl, hash))385386/**387* rht_for_each - iterate over hash chain388* @pos: the &struct rhash_head to use as a loop cursor.389* @tbl: the &struct bucket_table390* @hash: the hash value / bucket index391*/392#define rht_for_each(pos, tbl, hash) \393rht_for_each_continue(pos, (tbl)->buckets[hash], tbl, hash)394395/**396* rht_for_each_entry_continue - continue iterating over hash chain397* @tpos: the type * to use as a loop cursor.398* @pos: the &struct rhash_head to use as a loop cursor.399* @head: the previous &struct rhash_head to continue from400* @tbl: the &struct bucket_table401* @hash: the hash value / bucket index402* @member: name of the &struct rhash_head within the hashable struct.403*/404#define rht_for_each_entry_continue(tpos, pos, head, tbl, hash, member) \405for (pos = rht_dereference_bucket(head, tbl, hash); \406(!rht_is_a_nulls(pos)) && rht_entry(tpos, pos, member); \407pos = rht_dereference_bucket((pos)->next, tbl, hash))408409/**410* rht_for_each_entry - iterate over hash chain of given type411* @tpos: the type * to use as a loop cursor.412* @pos: the &struct rhash_head to use as a loop cursor.413* @tbl: the &struct bucket_table414* @hash: the hash value / bucket index415* @member: name of the &struct rhash_head within the hashable struct.416*/417#define rht_for_each_entry(tpos, pos, tbl, hash, member) \418rht_for_each_entry_continue(tpos, pos, (tbl)->buckets[hash], \419tbl, hash, member)420421/**422* rht_for_each_entry_safe - safely iterate over hash chain of given type423* @tpos: the type * to use as a loop cursor.424* @pos: the &struct rhash_head to use as a loop cursor.425* @next: the &struct rhash_head to use as next in loop cursor.426* @tbl: the &struct bucket_table427* @hash: the hash value / bucket index428* @member: name of the &struct rhash_head within the hashable struct.429*430* This hash chain list-traversal primitive allows for the looped code to431* remove the loop cursor from the list.432*/433#define rht_for_each_entry_safe(tpos, pos, next, tbl, hash, member) \434for (pos = rht_dereference_bucket((tbl)->buckets[hash], tbl, hash), \435next = !rht_is_a_nulls(pos) ? \436rht_dereference_bucket(pos->next, tbl, hash) : NULL; \437(!rht_is_a_nulls(pos)) && rht_entry(tpos, pos, member); \438pos = next, \439next = !rht_is_a_nulls(pos) ? \440rht_dereference_bucket(pos->next, tbl, hash) : NULL)441442/**443* rht_for_each_rcu_continue - continue iterating over rcu hash chain444* @pos: the &struct rhash_head to use as a loop cursor.445* @head: the previous &struct rhash_head to continue from446* @tbl: the &struct bucket_table447* @hash: the hash value / bucket index448*449* This hash chain list-traversal primitive may safely run concurrently with450* the _rcu mutation primitives such as rhashtable_insert() as long as the451* traversal is guarded by rcu_read_lock().452*/453#define rht_for_each_rcu_continue(pos, head, tbl, hash) \454for (({barrier(); }), \455pos = rht_dereference_bucket_rcu(head, tbl, hash); \456!rht_is_a_nulls(pos); \457pos = rcu_dereference_raw(pos->next))458459/**460* rht_for_each_rcu - iterate over rcu hash chain461* @pos: the &struct rhash_head to use as a loop cursor.462* @tbl: the &struct bucket_table463* @hash: the hash value / bucket index464*465* This hash chain list-traversal primitive may safely run concurrently with466* the _rcu mutation primitives such as rhashtable_insert() as long as the467* traversal is guarded by rcu_read_lock().468*/469#define rht_for_each_rcu(pos, tbl, hash) \470rht_for_each_rcu_continue(pos, (tbl)->buckets[hash], tbl, hash)471472/**473* rht_for_each_entry_rcu_continue - continue iterating over rcu hash chain474* @tpos: the type * to use as a loop cursor.475* @pos: the &struct rhash_head to use as a loop cursor.476* @head: the previous &struct rhash_head to continue from477* @tbl: the &struct bucket_table478* @hash: the hash value / bucket index479* @member: name of the &struct rhash_head within the hashable struct.480*481* This hash chain list-traversal primitive may safely run concurrently with482* the _rcu mutation primitives such as rhashtable_insert() as long as the483* traversal is guarded by rcu_read_lock().484*/485#define rht_for_each_entry_rcu_continue(tpos, pos, head, tbl, hash, member) \486for (({barrier(); }), \487pos = rht_dereference_bucket_rcu(head, tbl, hash); \488(!rht_is_a_nulls(pos)) && rht_entry(tpos, pos, member); \489pos = rht_dereference_bucket_rcu(pos->next, tbl, hash))490491/**492* rht_for_each_entry_rcu - iterate over rcu hash chain of given type493* @tpos: the type * to use as a loop cursor.494* @pos: the &struct rhash_head to use as a loop cursor.495* @tbl: the &struct bucket_table496* @hash: the hash value / bucket index497* @member: name of the &struct rhash_head within the hashable struct.498*499* This hash chain list-traversal primitive may safely run concurrently with500* the _rcu mutation primitives such as rhashtable_insert() as long as the501* traversal is guarded by rcu_read_lock().502*/503#define rht_for_each_entry_rcu(tpos, pos, tbl, hash, member) \504rht_for_each_entry_rcu_continue(tpos, pos, (tbl)->buckets[hash],\505tbl, hash, member)506507static inline int rhashtable_compare(struct rhashtable_compare_arg *arg,508const void *obj)509{510struct rhashtable *ht = arg->ht;511const char *ptr = obj;512513return memcmp(ptr + ht->p.key_offset, arg->key, ht->p.key_len);514}515516/**517* rhashtable_lookup_fast - search hash table, inlined version518* @ht: hash table519* @key: the pointer to the key520* @params: hash table parameters521*522* Computes the hash value for the key and traverses the bucket chain looking523* for a entry with an identical key. The first matching entry is returned.524*525* Returns the first entry on which the compare function returned true.526*/527static inline void *rhashtable_lookup_fast(528struct rhashtable *ht, const void *key,529const struct rhashtable_params params)530{531struct rhashtable_compare_arg arg = {532.ht = ht,533.key = key,534};535const struct bucket_table *tbl;536struct rhash_head *he;537unsigned int hash;538539rcu_read_lock();540541tbl = rht_dereference_rcu(ht->tbl, ht);542restart:543hash = rht_key_hashfn(ht, tbl, key, params);544rht_for_each_rcu(he, tbl, hash) {545if (params.obj_cmpfn ?546params.obj_cmpfn(&arg, rht_obj(ht, he)) :547rhashtable_compare(&arg, rht_obj(ht, he)))548continue;549rcu_read_unlock();550return rht_obj(ht, he);551}552553/* Ensure we see any new tables. */554smp_rmb();555556tbl = rht_dereference_rcu(tbl->future_tbl, ht);557if (unlikely(tbl))558goto restart;559rcu_read_unlock();560561return NULL;562}563564/* Internal function, please use rhashtable_insert_fast() instead */565static inline int __rhashtable_insert_fast(566struct rhashtable *ht, const void *key, struct rhash_head *obj,567const struct rhashtable_params params)568{569struct rhashtable_compare_arg arg = {570.ht = ht,571.key = key,572};573struct bucket_table *tbl, *new_tbl;574struct rhash_head *head;575spinlock_t *lock;576unsigned int elasticity;577unsigned int hash;578int err;579580restart:581rcu_read_lock();582583tbl = rht_dereference_rcu(ht->tbl, ht);584585/* All insertions must grab the oldest table containing586* the hashed bucket that is yet to be rehashed.587*/588for (;;) {589hash = rht_head_hashfn(ht, tbl, obj, params);590lock = rht_bucket_lock(tbl, hash);591spin_lock_bh(lock);592593if (tbl->rehash <= hash)594break;595596spin_unlock_bh(lock);597tbl = rht_dereference_rcu(tbl->future_tbl, ht);598}599600new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);601if (unlikely(new_tbl)) {602tbl = rhashtable_insert_slow(ht, key, obj, new_tbl);603if (!IS_ERR_OR_NULL(tbl))604goto slow_path;605606err = PTR_ERR(tbl);607goto out;608}609610err = -E2BIG;611if (unlikely(rht_grow_above_max(ht, tbl)))612goto out;613614if (unlikely(rht_grow_above_100(ht, tbl))) {615slow_path:616spin_unlock_bh(lock);617err = rhashtable_insert_rehash(ht, tbl);618rcu_read_unlock();619if (err)620return err;621622goto restart;623}624625err = -EEXIST;626elasticity = ht->elasticity;627rht_for_each(head, tbl, hash) {628if (key &&629unlikely(!(params.obj_cmpfn ?630params.obj_cmpfn(&arg, rht_obj(ht, head)) :631rhashtable_compare(&arg, rht_obj(ht, head)))))632goto out;633if (!--elasticity)634goto slow_path;635}636637err = 0;638639head = rht_dereference_bucket(tbl->buckets[hash], tbl, hash);640641RCU_INIT_POINTER(obj->next, head);642643rcu_assign_pointer(tbl->buckets[hash], obj);644645atomic_inc(&ht->nelems);646if (rht_grow_above_75(ht, tbl))647schedule_work(&ht->run_work);648649out:650spin_unlock_bh(lock);651rcu_read_unlock();652653return err;654}655656/**657* rhashtable_insert_fast - insert object into hash table658* @ht: hash table659* @obj: pointer to hash head inside object660* @params: hash table parameters661*662* Will take a per bucket spinlock to protect against mutual mutations663* on the same bucket. Multiple insertions may occur in parallel unless664* they map to the same bucket lock.665*666* It is safe to call this function from atomic context.667*668* Will trigger an automatic deferred table resizing if the size grows669* beyond the watermark indicated by grow_decision() which can be passed670* to rhashtable_init().671*/672static inline int rhashtable_insert_fast(673struct rhashtable *ht, struct rhash_head *obj,674const struct rhashtable_params params)675{676return __rhashtable_insert_fast(ht, NULL, obj, params);677}678679/**680* rhashtable_lookup_insert_fast - lookup and insert object into hash table681* @ht: hash table682* @obj: pointer to hash head inside object683* @params: hash table parameters684*685* Locks down the bucket chain in both the old and new table if a resize686* is in progress to ensure that writers can't remove from the old table687* and can't insert to the new table during the atomic operation of search688* and insertion. Searches for duplicates in both the old and new table if689* a resize is in progress.690*691* This lookup function may only be used for fixed key hash table (key_len692* parameter set). It will BUG() if used inappropriately.693*694* It is safe to call this function from atomic context.695*696* Will trigger an automatic deferred table resizing if the size grows697* beyond the watermark indicated by grow_decision() which can be passed698* to rhashtable_init().699*/700static inline int rhashtable_lookup_insert_fast(701struct rhashtable *ht, struct rhash_head *obj,702const struct rhashtable_params params)703{704const char *key = rht_obj(ht, obj);705706BUG_ON(ht->p.obj_hashfn);707708return __rhashtable_insert_fast(ht, key + ht->p.key_offset, obj,709params);710}711712/**713* rhashtable_lookup_insert_key - search and insert object to hash table714* with explicit key715* @ht: hash table716* @key: key717* @obj: pointer to hash head inside object718* @params: hash table parameters719*720* Locks down the bucket chain in both the old and new table if a resize721* is in progress to ensure that writers can't remove from the old table722* and can't insert to the new table during the atomic operation of search723* and insertion. Searches for duplicates in both the old and new table if724* a resize is in progress.725*726* Lookups may occur in parallel with hashtable mutations and resizing.727*728* Will trigger an automatic deferred table resizing if the size grows729* beyond the watermark indicated by grow_decision() which can be passed730* to rhashtable_init().731*732* Returns zero on success.733*/734static inline int rhashtable_lookup_insert_key(735struct rhashtable *ht, const void *key, struct rhash_head *obj,736const struct rhashtable_params params)737{738BUG_ON(!ht->p.obj_hashfn || !key);739740return __rhashtable_insert_fast(ht, key, obj, params);741}742743/* Internal function, please use rhashtable_remove_fast() instead */744static inline int __rhashtable_remove_fast(745struct rhashtable *ht, struct bucket_table *tbl,746struct rhash_head *obj, const struct rhashtable_params params)747{748struct rhash_head __rcu **pprev;749struct rhash_head *he;750spinlock_t * lock;751unsigned int hash;752int err = -ENOENT;753754hash = rht_head_hashfn(ht, tbl, obj, params);755lock = rht_bucket_lock(tbl, hash);756757spin_lock_bh(lock);758759pprev = &tbl->buckets[hash];760rht_for_each(he, tbl, hash) {761if (he != obj) {762pprev = &he->next;763continue;764}765766rcu_assign_pointer(*pprev, obj->next);767err = 0;768break;769}770771spin_unlock_bh(lock);772773return err;774}775776/**777* rhashtable_remove_fast - remove object from hash table778* @ht: hash table779* @obj: pointer to hash head inside object780* @params: hash table parameters781*782* Since the hash chain is single linked, the removal operation needs to783* walk the bucket chain upon removal. The removal operation is thus784* considerable slow if the hash table is not correctly sized.785*786* Will automatically shrink the table via rhashtable_expand() if the787* shrink_decision function specified at rhashtable_init() returns true.788*789* Returns zero on success, -ENOENT if the entry could not be found.790*/791static inline int rhashtable_remove_fast(792struct rhashtable *ht, struct rhash_head *obj,793const struct rhashtable_params params)794{795struct bucket_table *tbl;796int err;797798rcu_read_lock();799800tbl = rht_dereference_rcu(ht->tbl, ht);801802/* Because we have already taken (and released) the bucket803* lock in old_tbl, if we find that future_tbl is not yet804* visible then that guarantees the entry to still be in805* the old tbl if it exists.806*/807while ((err = __rhashtable_remove_fast(ht, tbl, obj, params)) &&808(tbl = rht_dereference_rcu(tbl->future_tbl, ht)))809;810811if (err)812goto out;813814atomic_dec(&ht->nelems);815if (unlikely(ht->p.automatic_shrinking &&816rht_shrink_below_30(ht, tbl)))817schedule_work(&ht->run_work);818819out:820rcu_read_unlock();821822return err;823}824825#endif /* _LINUX_RHASHTABLE_H */826827828829