Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/rhashtable.c
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#include <linux/atomic.h>17#include <linux/kernel.h>18#include <linux/init.h>19#include <linux/log2.h>20#include <linux/sched.h>21#include <linux/slab.h>22#include <linux/vmalloc.h>23#include <linux/mm.h>24#include <linux/jhash.h>25#include <linux/random.h>26#include <linux/err.h>27#include <linux/export.h>2829#define HASH_DEFAULT_SIZE 64UL30#define HASH_MIN_SIZE 4U31#define BUCKET_LOCKS_PER_CPU 128UL3233static u32 head_hashfn(struct rhashtable *ht,34const struct bucket_table *tbl,35const struct rhash_head *he)36{37return rht_head_hashfn(ht, tbl, he, ht->p);38}3940#ifdef CONFIG_PROVE_LOCKING41#define ASSERT_RHT_MUTEX(HT) BUG_ON(!lockdep_rht_mutex_is_held(HT))4243int lockdep_rht_mutex_is_held(struct rhashtable *ht)44{45return (debug_locks) ? lockdep_is_held(&ht->mutex) : 1;46}4748int lockdep_rht_bucket_is_held(const struct bucket_table *tbl, u32 hash)49{50spinlock_t *lock = rht_bucket_lock(tbl, hash);5152return (debug_locks) ? lockdep_is_held(lock) : 1;53}54#else55#define ASSERT_RHT_MUTEX(HT)56#endif575859static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl,60gfp_t gfp)61{62unsigned int i, size;63#if defined(CONFIG_PROVE_LOCKING)64unsigned int nr_pcpus = 2;65#else66unsigned int nr_pcpus = num_possible_cpus();67#endif6869nr_pcpus = min_t(unsigned int, nr_pcpus, 32UL);70size = roundup_pow_of_two(nr_pcpus * ht->p.locks_mul);7172/* Never allocate more than 0.5 locks per bucket */73size = min_t(unsigned int, size, tbl->size >> 1);7475if (sizeof(spinlock_t) != 0) {76#ifdef CONFIG_NUMA77if (size * sizeof(spinlock_t) > PAGE_SIZE &&78gfp == GFP_KERNEL)79tbl->locks = vmalloc(size * sizeof(spinlock_t));80else81#endif82tbl->locks = kmalloc_array(size, sizeof(spinlock_t),83gfp);84if (!tbl->locks)85return -ENOMEM;86for (i = 0; i < size; i++)87spin_lock_init(&tbl->locks[i]);88}89tbl->locks_mask = size - 1;9091return 0;92}9394static void bucket_table_free(const struct bucket_table *tbl)95{96if (tbl)97kvfree(tbl->locks);9899kvfree(tbl);100}101102static void bucket_table_free_rcu(struct rcu_head *head)103{104bucket_table_free(container_of(head, struct bucket_table, rcu));105}106107static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,108size_t nbuckets,109gfp_t gfp)110{111struct bucket_table *tbl = NULL;112size_t size;113int i;114115size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]);116if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER) ||117gfp != GFP_KERNEL)118tbl = kzalloc(size, gfp | __GFP_NOWARN | __GFP_NORETRY);119if (tbl == NULL && gfp == GFP_KERNEL)120tbl = vzalloc(size);121if (tbl == NULL)122return NULL;123124tbl->size = nbuckets;125126if (alloc_bucket_locks(ht, tbl, gfp) < 0) {127bucket_table_free(tbl);128return NULL;129}130131INIT_LIST_HEAD(&tbl->walkers);132133get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));134135for (i = 0; i < nbuckets; i++)136INIT_RHT_NULLS_HEAD(tbl->buckets[i], ht, i);137138return tbl;139}140141static struct bucket_table *rhashtable_last_table(struct rhashtable *ht,142struct bucket_table *tbl)143{144struct bucket_table *new_tbl;145146do {147new_tbl = tbl;148tbl = rht_dereference_rcu(tbl->future_tbl, ht);149} while (tbl);150151return new_tbl;152}153154static int rhashtable_rehash_one(struct rhashtable *ht, unsigned int old_hash)155{156struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);157struct bucket_table *new_tbl = rhashtable_last_table(ht,158rht_dereference_rcu(old_tbl->future_tbl, ht));159struct rhash_head __rcu **pprev = &old_tbl->buckets[old_hash];160int err = -ENOENT;161struct rhash_head *head, *next, *entry;162spinlock_t *new_bucket_lock;163unsigned int new_hash;164165rht_for_each(entry, old_tbl, old_hash) {166err = 0;167next = rht_dereference_bucket(entry->next, old_tbl, old_hash);168169if (rht_is_a_nulls(next))170break;171172pprev = &entry->next;173}174175if (err)176goto out;177178new_hash = head_hashfn(ht, new_tbl, entry);179180new_bucket_lock = rht_bucket_lock(new_tbl, new_hash);181182spin_lock_nested(new_bucket_lock, SINGLE_DEPTH_NESTING);183head = rht_dereference_bucket(new_tbl->buckets[new_hash],184new_tbl, new_hash);185186RCU_INIT_POINTER(entry->next, head);187188rcu_assign_pointer(new_tbl->buckets[new_hash], entry);189spin_unlock(new_bucket_lock);190191rcu_assign_pointer(*pprev, next);192193out:194return err;195}196197static void rhashtable_rehash_chain(struct rhashtable *ht,198unsigned int old_hash)199{200struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);201spinlock_t *old_bucket_lock;202203old_bucket_lock = rht_bucket_lock(old_tbl, old_hash);204205spin_lock_bh(old_bucket_lock);206while (!rhashtable_rehash_one(ht, old_hash))207;208old_tbl->rehash++;209spin_unlock_bh(old_bucket_lock);210}211212static int rhashtable_rehash_attach(struct rhashtable *ht,213struct bucket_table *old_tbl,214struct bucket_table *new_tbl)215{216/* Protect future_tbl using the first bucket lock. */217spin_lock_bh(old_tbl->locks);218219/* Did somebody beat us to it? */220if (rcu_access_pointer(old_tbl->future_tbl)) {221spin_unlock_bh(old_tbl->locks);222return -EEXIST;223}224225/* Make insertions go into the new, empty table right away. Deletions226* and lookups will be attempted in both tables until we synchronize.227*/228rcu_assign_pointer(old_tbl->future_tbl, new_tbl);229230/* Ensure the new table is visible to readers. */231smp_wmb();232233spin_unlock_bh(old_tbl->locks);234235return 0;236}237238static int rhashtable_rehash_table(struct rhashtable *ht)239{240struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);241struct bucket_table *new_tbl;242struct rhashtable_walker *walker;243unsigned int old_hash;244245new_tbl = rht_dereference(old_tbl->future_tbl, ht);246if (!new_tbl)247return 0;248249for (old_hash = 0; old_hash < old_tbl->size; old_hash++)250rhashtable_rehash_chain(ht, old_hash);251252/* Publish the new table pointer. */253rcu_assign_pointer(ht->tbl, new_tbl);254255spin_lock(&ht->lock);256list_for_each_entry(walker, &old_tbl->walkers, list)257walker->tbl = NULL;258spin_unlock(&ht->lock);259260/* Wait for readers. All new readers will see the new261* table, and thus no references to the old table will262* remain.263*/264call_rcu(&old_tbl->rcu, bucket_table_free_rcu);265266return rht_dereference(new_tbl->future_tbl, ht) ? -EAGAIN : 0;267}268269/**270* rhashtable_expand - Expand hash table while allowing concurrent lookups271* @ht: the hash table to expand272*273* A secondary bucket array is allocated and the hash entries are migrated.274*275* This function may only be called in a context where it is safe to call276* synchronize_rcu(), e.g. not within a rcu_read_lock() section.277*278* The caller must ensure that no concurrent resizing occurs by holding279* ht->mutex.280*281* It is valid to have concurrent insertions and deletions protected by per282* bucket locks or concurrent RCU protected lookups and traversals.283*/284static int rhashtable_expand(struct rhashtable *ht)285{286struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht);287int err;288289ASSERT_RHT_MUTEX(ht);290291old_tbl = rhashtable_last_table(ht, old_tbl);292293new_tbl = bucket_table_alloc(ht, old_tbl->size * 2, GFP_KERNEL);294if (new_tbl == NULL)295return -ENOMEM;296297err = rhashtable_rehash_attach(ht, old_tbl, new_tbl);298if (err)299bucket_table_free(new_tbl);300301return err;302}303304/**305* rhashtable_shrink - Shrink hash table while allowing concurrent lookups306* @ht: the hash table to shrink307*308* This function shrinks the hash table to fit, i.e., the smallest309* size would not cause it to expand right away automatically.310*311* The caller must ensure that no concurrent resizing occurs by holding312* ht->mutex.313*314* The caller must ensure that no concurrent table mutations take place.315* It is however valid to have concurrent lookups if they are RCU protected.316*317* It is valid to have concurrent insertions and deletions protected by per318* bucket locks or concurrent RCU protected lookups and traversals.319*/320static int rhashtable_shrink(struct rhashtable *ht)321{322struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht);323unsigned int size;324int err;325326ASSERT_RHT_MUTEX(ht);327328size = roundup_pow_of_two(atomic_read(&ht->nelems) * 3 / 2);329if (size < ht->p.min_size)330size = ht->p.min_size;331332if (old_tbl->size <= size)333return 0;334335if (rht_dereference(old_tbl->future_tbl, ht))336return -EEXIST;337338new_tbl = bucket_table_alloc(ht, size, GFP_KERNEL);339if (new_tbl == NULL)340return -ENOMEM;341342err = rhashtable_rehash_attach(ht, old_tbl, new_tbl);343if (err)344bucket_table_free(new_tbl);345346return err;347}348349static void rht_deferred_worker(struct work_struct *work)350{351struct rhashtable *ht;352struct bucket_table *tbl;353int err = 0;354355ht = container_of(work, struct rhashtable, run_work);356mutex_lock(&ht->mutex);357358tbl = rht_dereference(ht->tbl, ht);359tbl = rhashtable_last_table(ht, tbl);360361if (rht_grow_above_75(ht, tbl))362rhashtable_expand(ht);363else if (ht->p.automatic_shrinking && rht_shrink_below_30(ht, tbl))364rhashtable_shrink(ht);365366err = rhashtable_rehash_table(ht);367368mutex_unlock(&ht->mutex);369370if (err)371schedule_work(&ht->run_work);372}373374static bool rhashtable_check_elasticity(struct rhashtable *ht,375struct bucket_table *tbl,376unsigned int hash)377{378unsigned int elasticity = ht->elasticity;379struct rhash_head *head;380381rht_for_each(head, tbl, hash)382if (!--elasticity)383return true;384385return false;386}387388int rhashtable_insert_rehash(struct rhashtable *ht,389struct bucket_table *tbl)390{391struct bucket_table *old_tbl;392struct bucket_table *new_tbl;393unsigned int size;394int err;395396old_tbl = rht_dereference_rcu(ht->tbl, ht);397398size = tbl->size;399400err = -EBUSY;401402if (rht_grow_above_75(ht, tbl))403size *= 2;404/* Do not schedule more than one rehash */405else if (old_tbl != tbl)406goto fail;407408err = -ENOMEM;409410new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC);411if (new_tbl == NULL)412goto fail;413414err = rhashtable_rehash_attach(ht, tbl, new_tbl);415if (err) {416bucket_table_free(new_tbl);417if (err == -EEXIST)418err = 0;419} else420schedule_work(&ht->run_work);421422return err;423424fail:425/* Do not fail the insert if someone else did a rehash. */426if (likely(rcu_dereference_raw(tbl->future_tbl)))427return 0;428429/* Schedule async rehash to retry allocation in process context. */430if (err == -ENOMEM)431schedule_work(&ht->run_work);432433return err;434}435436struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,437const void *key,438struct rhash_head *obj,439struct bucket_table *tbl)440{441struct rhash_head *head;442unsigned int hash;443int err;444445tbl = rhashtable_last_table(ht, tbl);446hash = head_hashfn(ht, tbl, obj);447spin_lock_nested(rht_bucket_lock(tbl, hash), SINGLE_DEPTH_NESTING);448449err = -EEXIST;450if (key && rhashtable_lookup_fast(ht, key, ht->p))451goto exit;452453err = -E2BIG;454if (unlikely(rht_grow_above_max(ht, tbl)))455goto exit;456457err = -EAGAIN;458if (rhashtable_check_elasticity(ht, tbl, hash) ||459rht_grow_above_100(ht, tbl))460goto exit;461462err = 0;463464head = rht_dereference_bucket(tbl->buckets[hash], tbl, hash);465466RCU_INIT_POINTER(obj->next, head);467468rcu_assign_pointer(tbl->buckets[hash], obj);469470atomic_inc(&ht->nelems);471472exit:473spin_unlock(rht_bucket_lock(tbl, hash));474475if (err == 0)476return NULL;477else if (err == -EAGAIN)478return tbl;479else480return ERR_PTR(err);481}482483/**484* rhashtable_walk_init - Initialise an iterator485* @ht: Table to walk over486* @iter: Hash table Iterator487*488* This function prepares a hash table walk.489*490* Note that if you restart a walk after rhashtable_walk_stop you491* may see the same object twice. Also, you may miss objects if492* there are removals in between rhashtable_walk_stop and the next493* call to rhashtable_walk_start.494*495* For a completely stable walk you should construct your own data496* structure outside the hash table.497*498* This function may sleep so you must not call it from interrupt499* context or with spin locks held.500*501* You must call rhashtable_walk_exit if this function returns502* successfully.503*/504int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter)505{506iter->ht = ht;507iter->p = NULL;508iter->slot = 0;509iter->skip = 0;510511iter->walker = kmalloc(sizeof(*iter->walker), GFP_KERNEL);512if (!iter->walker)513return -ENOMEM;514515spin_lock(&ht->lock);516iter->walker->tbl =517rcu_dereference_protected(ht->tbl, lockdep_is_held(&ht->lock));518list_add(&iter->walker->list, &iter->walker->tbl->walkers);519spin_unlock(&ht->lock);520521return 0;522}523524/**525* rhashtable_walk_exit - Free an iterator526* @iter: Hash table Iterator527*528* This function frees resources allocated by rhashtable_walk_init.529*/530void rhashtable_walk_exit(struct rhashtable_iter *iter)531{532spin_lock(&iter->ht->lock);533if (iter->walker->tbl)534list_del(&iter->walker->list);535spin_unlock(&iter->ht->lock);536kfree(iter->walker);537}538539/**540* rhashtable_walk_start - Start a hash table walk541* @iter: Hash table iterator542*543* Start a hash table walk. Note that we take the RCU lock in all544* cases including when we return an error. So you must always call545* rhashtable_walk_stop to clean up.546*547* Returns zero if successful.548*549* Returns -EAGAIN if resize event occured. Note that the iterator550* will rewind back to the beginning and you may use it immediately551* by calling rhashtable_walk_next.552*/553int rhashtable_walk_start(struct rhashtable_iter *iter)554__acquires(RCU)555{556struct rhashtable *ht = iter->ht;557558rcu_read_lock();559560spin_lock(&ht->lock);561if (iter->walker->tbl)562list_del(&iter->walker->list);563spin_unlock(&ht->lock);564565if (!iter->walker->tbl) {566iter->walker->tbl = rht_dereference_rcu(ht->tbl, ht);567return -EAGAIN;568}569570return 0;571}572573/**574* rhashtable_walk_next - Return the next object and advance the iterator575* @iter: Hash table iterator576*577* Note that you must call rhashtable_walk_stop when you are finished578* with the walk.579*580* Returns the next object or NULL when the end of the table is reached.581*582* Returns -EAGAIN if resize event occured. Note that the iterator583* will rewind back to the beginning and you may continue to use it.584*/585void *rhashtable_walk_next(struct rhashtable_iter *iter)586{587struct bucket_table *tbl = iter->walker->tbl;588struct rhashtable *ht = iter->ht;589struct rhash_head *p = iter->p;590591if (p) {592p = rht_dereference_bucket_rcu(p->next, tbl, iter->slot);593goto next;594}595596for (; iter->slot < tbl->size; iter->slot++) {597int skip = iter->skip;598599rht_for_each_rcu(p, tbl, iter->slot) {600if (!skip)601break;602skip--;603}604605next:606if (!rht_is_a_nulls(p)) {607iter->skip++;608iter->p = p;609return rht_obj(ht, p);610}611612iter->skip = 0;613}614615iter->p = NULL;616617/* Ensure we see any new tables. */618smp_rmb();619620iter->walker->tbl = rht_dereference_rcu(tbl->future_tbl, ht);621if (iter->walker->tbl) {622iter->slot = 0;623iter->skip = 0;624return ERR_PTR(-EAGAIN);625}626627return NULL;628}629630/**631* rhashtable_walk_stop - Finish a hash table walk632* @iter: Hash table iterator633*634* Finish a hash table walk.635*/636void rhashtable_walk_stop(struct rhashtable_iter *iter)637__releases(RCU)638{639struct rhashtable *ht;640struct bucket_table *tbl = iter->walker->tbl;641642if (!tbl)643goto out;644645ht = iter->ht;646647spin_lock(&ht->lock);648if (tbl->rehash < tbl->size)649list_add(&iter->walker->list, &tbl->walkers);650else651iter->walker->tbl = NULL;652spin_unlock(&ht->lock);653654iter->p = NULL;655656out:657rcu_read_unlock();658}659660static size_t rounded_hashtable_size(const struct rhashtable_params *params)661{662return max(roundup_pow_of_two(params->nelem_hint * 4 / 3),663(unsigned long)params->min_size);664}665666static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)667{668return jhash2(key, length, seed);669}670671/**672* rhashtable_init - initialize a new hash table673* @ht: hash table to be initialized674* @params: configuration parameters675*676* Initializes a new hash table based on the provided configuration677* parameters. A table can be configured either with a variable or678* fixed length key:679*680* Configuration Example 1: Fixed length keys681* struct test_obj {682* int key;683* void * my_member;684* struct rhash_head node;685* };686*687* struct rhashtable_params params = {688* .head_offset = offsetof(struct test_obj, node),689* .key_offset = offsetof(struct test_obj, key),690* .key_len = sizeof(int),691* .hashfn = jhash,692* .nulls_base = (1U << RHT_BASE_SHIFT),693* };694*695* Configuration Example 2: Variable length keys696* struct test_obj {697* [...]698* struct rhash_head node;699* };700*701* u32 my_hash_fn(const void *data, u32 len, u32 seed)702* {703* struct test_obj *obj = data;704*705* return [... hash ...];706* }707*708* struct rhashtable_params params = {709* .head_offset = offsetof(struct test_obj, node),710* .hashfn = jhash,711* .obj_hashfn = my_hash_fn,712* };713*/714int rhashtable_init(struct rhashtable *ht,715const struct rhashtable_params *params)716{717struct bucket_table *tbl;718size_t size;719720size = HASH_DEFAULT_SIZE;721722if ((!params->key_len && !params->obj_hashfn) ||723(params->obj_hashfn && !params->obj_cmpfn))724return -EINVAL;725726if (params->nulls_base && params->nulls_base < (1U << RHT_BASE_SHIFT))727return -EINVAL;728729memset(ht, 0, sizeof(*ht));730mutex_init(&ht->mutex);731spin_lock_init(&ht->lock);732memcpy(&ht->p, params, sizeof(*params));733734if (params->min_size)735ht->p.min_size = roundup_pow_of_two(params->min_size);736737if (params->max_size)738ht->p.max_size = rounddown_pow_of_two(params->max_size);739740if (params->insecure_max_entries)741ht->p.insecure_max_entries =742rounddown_pow_of_two(params->insecure_max_entries);743else744ht->p.insecure_max_entries = ht->p.max_size * 2;745746ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);747748if (params->nelem_hint)749size = rounded_hashtable_size(&ht->p);750751/* The maximum (not average) chain length grows with the752* size of the hash table, at a rate of (log N)/(log log N).753* The value of 16 is selected so that even if the hash754* table grew to 2^32 you would not expect the maximum755* chain length to exceed it unless we are under attack756* (or extremely unlucky).757*758* As this limit is only to detect attacks, we don't need759* to set it to a lower value as you'd need the chain760* length to vastly exceed 16 to have any real effect761* on the system.762*/763if (!params->insecure_elasticity)764ht->elasticity = 16;765766if (params->locks_mul)767ht->p.locks_mul = roundup_pow_of_two(params->locks_mul);768else769ht->p.locks_mul = BUCKET_LOCKS_PER_CPU;770771ht->key_len = ht->p.key_len;772if (!params->hashfn) {773ht->p.hashfn = jhash;774775if (!(ht->key_len & (sizeof(u32) - 1))) {776ht->key_len /= sizeof(u32);777ht->p.hashfn = rhashtable_jhash2;778}779}780781tbl = bucket_table_alloc(ht, size, GFP_KERNEL);782if (tbl == NULL)783return -ENOMEM;784785atomic_set(&ht->nelems, 0);786787RCU_INIT_POINTER(ht->tbl, tbl);788789INIT_WORK(&ht->run_work, rht_deferred_worker);790791return 0;792}793794/**795* rhashtable_free_and_destroy - free elements and destroy hash table796* @ht: the hash table to destroy797* @free_fn: callback to release resources of element798* @arg: pointer passed to free_fn799*800* Stops an eventual async resize. If defined, invokes free_fn for each801* element to releasal resources. Please note that RCU protected802* readers may still be accessing the elements. Releasing of resources803* must occur in a compatible manner. Then frees the bucket array.804*805* This function will eventually sleep to wait for an async resize806* to complete. The caller is responsible that no further write operations807* occurs in parallel.808*/809void rhashtable_free_and_destroy(struct rhashtable *ht,810void (*free_fn)(void *ptr, void *arg),811void *arg)812{813const struct bucket_table *tbl;814unsigned int i;815816cancel_work_sync(&ht->run_work);817818mutex_lock(&ht->mutex);819tbl = rht_dereference(ht->tbl, ht);820if (free_fn) {821for (i = 0; i < tbl->size; i++) {822struct rhash_head *pos, *next;823824for (pos = rht_dereference(tbl->buckets[i], ht),825next = !rht_is_a_nulls(pos) ?826rht_dereference(pos->next, ht) : NULL;827!rht_is_a_nulls(pos);828pos = next,829next = !rht_is_a_nulls(pos) ?830rht_dereference(pos->next, ht) : NULL)831free_fn(rht_obj(ht, pos), arg);832}833}834835bucket_table_free(tbl);836mutex_unlock(&ht->mutex);837}838839void rhashtable_destroy(struct rhashtable *ht)840{841return rhashtable_free_and_destroy(ht, NULL, NULL);842}843844845846