/*********************************************************************1*2* Filename: irqueue.c3* Version: 0.34* Description: General queue implementation5* Status: Experimental.6* Author: Dag Brattli <[email protected]>7* Created at: Tue Jun 9 13:29:31 19988* Modified at: Sun Dec 12 13:48:22 19999* Modified by: Dag Brattli <[email protected]>10* Modified at: Thu Jan 4 14:29:10 CET 200111* Modified by: Marc Zyngier <[email protected]>12*13* Copyright (C) 1998-1999, Aage Kvalnes <[email protected]>14* Copyright (C) 1998, Dag Brattli,15* All Rights Reserved.16*17* This code is taken from the Vortex Operating System written by Aage18* Kvalnes. Aage has agreed that this code can use the GPL licence,19* although he does not use that licence in his own code.20*21* This copyright does however _not_ include the ELF hash() function22* which I currently don't know which licence or copyright it23* has. Please inform me if you know.24*25* This program is free software; you can redistribute it and/or26* modify it under the terms of the GNU General Public License as27* published by the Free Software Foundation; either version 2 of28* the License, or (at your option) any later version.29*30* Neither Dag Brattli nor University of Tromsø admit liability nor31* provide warranty for any of this software. This material is32* provided "AS-IS" and at no charge.33*34********************************************************************/3536/*37* NOTE :38* There are various problems with this package :39* o the hash function for ints is pathetic (but could be changed)40* o locking is sometime suspicious (especially during enumeration)41* o most users have only a few elements (== overhead)42* o most users never use search, so don't benefit from hashing43* Problem already fixed :44* o not 64 bit compliant (most users do hashv = (int) self)45* o hashbin_remove() is broken => use hashbin_remove_this()46* I think most users would be better served by a simple linked list47* (like include/linux/list.h) with a global spinlock per list.48* Jean II49*/5051/*52* Notes on the concurrent access to hashbin and other SMP issues53* -------------------------------------------------------------54* Hashbins are very often in the IrDA stack a global repository of55* information, and therefore used in a very asynchronous manner following56* various events (driver calls, timers, user calls...).57* Therefore, very often it is highly important to consider the58* management of concurrent access to the hashbin and how to guarantee the59* consistency of the operations on it.60*61* First, we need to define the objective of locking :62* 1) Protect user data (content pointed by the hashbin)63* 2) Protect hashbin structure itself (linked list in each bin)64*65* OLD LOCKING66* -----------67*68* The previous locking strategy, either HB_LOCAL or HB_GLOBAL were69* both inadequate in *both* aspect.70* o HB_GLOBAL was using a spinlock for each bin (local locking).71* o HB_LOCAL was disabling irq on *all* CPUs, so use a single72* global semaphore.73* The problems were :74* A) Global irq disabling is no longer supported by the kernel75* B) No protection for the hashbin struct global data76* o hashbin_delete()77* o hb_current78* C) No protection for user data in some cases79*80* A) HB_LOCAL use global irq disabling, so doesn't work on kernel81* 2.5.X. Even when it is supported (kernel 2.4.X and earlier), its82* performance is not satisfactory on SMP setups. Most hashbins were83* HB_LOCAL, so (A) definitely need fixing.84* B) HB_LOCAL could be modified to fix (B). However, because HB_GLOBAL85* lock only the individual bins, it will never be able to lock the86* global data, so can't do (B).87* C) Some functions return pointer to data that is still in the88* hashbin :89* o hashbin_find()90* o hashbin_get_first()91* o hashbin_get_next()92* As the data is still in the hashbin, it may be changed or free'd93* while the caller is examinimg the data. In those case, locking can't94* be done within the hashbin, but must include use of the data within95* the caller.96* The caller can easily do this with HB_LOCAL (just disable irqs).97* However, this is impossible with HB_GLOBAL because the caller has no98* way to know the proper bin, so don't know which spinlock to use.99*100* Quick summary : can no longer use HB_LOCAL, and HB_GLOBAL is101* fundamentally broken and will never work.102*103* NEW LOCKING104* -----------105*106* To fix those problems, I've introduce a few changes in the107* hashbin locking :108* 1) New HB_LOCK scheme109* 2) hashbin->hb_spinlock110* 3) New hashbin usage policy111*112* HB_LOCK :113* -------114* HB_LOCK is a locking scheme intermediate between the old HB_LOCAL115* and HB_GLOBAL. It uses a single spinlock to protect the whole content116* of the hashbin. As it is a single spinlock, it can protect the global117* data of the hashbin and not only the bins themselves.118* HB_LOCK can only protect some of the hashbin calls, so it only lock119* call that can be made 100% safe and leave other call unprotected.120* HB_LOCK in theory is slower than HB_GLOBAL, but as the hashbin121* content is always small contention is not high, so it doesn't matter122* much. HB_LOCK is probably faster than HB_LOCAL.123*124* hashbin->hb_spinlock :125* --------------------126* The spinlock that HB_LOCK uses is available for caller, so that127* the caller can protect unprotected calls (see below).128* If the caller want to do entirely its own locking (HB_NOLOCK), he129* can do so and may use safely this spinlock.130* Locking is done like this :131* spin_lock_irqsave(&hashbin->hb_spinlock, flags);132* Releasing the lock :133* spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);134*135* Safe & Protected calls :136* ----------------------137* The following calls are safe or protected via HB_LOCK :138* o hashbin_new() -> safe139* o hashbin_delete()140* o hashbin_insert()141* o hashbin_remove_first()142* o hashbin_remove()143* o hashbin_remove_this()144* o HASHBIN_GET_SIZE() -> atomic145*146* The following calls only protect the hashbin itself :147* o hashbin_lock_find()148* o hashbin_find_next()149*150* Unprotected calls :151* -----------------152* The following calls need to be protected by the caller :153* o hashbin_find()154* o hashbin_get_first()155* o hashbin_get_next()156*157* Locking Policy :158* --------------159* If the hashbin is used only in a single thread of execution160* (explicitly or implicitely), you can use HB_NOLOCK161* If the calling module already provide concurrent access protection,162* you may use HB_NOLOCK.163*164* In all other cases, you need to use HB_LOCK and lock the hashbin165* every time before calling one of the unprotected calls. You also must166* use the pointer returned by the unprotected call within the locked167* region.168*169* Extra care for enumeration :170* --------------------------171* hashbin_get_first() and hashbin_get_next() use the hashbin to172* store the current position, in hb_current.173* As long as the hashbin remains locked, this is safe. If you unlock174* the hashbin, the current position may change if anybody else modify175* or enumerate the hashbin.176* Summary : do the full enumeration while locked.177*178* Alternatively, you may use hashbin_find_next(). But, this will179* be slower, is more complex to use and doesn't protect the hashbin180* content. So, care is needed here as well.181*182* Other issues :183* ------------184* I believe that we are overdoing it by using spin_lock_irqsave()185* and we should use only spin_lock_bh() or similar. But, I don't have186* the balls to try it out.187* Don't believe that because hashbin are now (somewhat) SMP safe188* that the rest of the code is. Higher layers tend to be safest,189* but LAP and LMP would need some serious dedicated love.190*191* Jean II192*/193#include <linux/module.h>194#include <linux/slab.h>195196#include <net/irda/irda.h>197#include <net/irda/irqueue.h>198199/************************ QUEUE SUBROUTINES ************************/200201/*202* Hashbin203*/204#define GET_HASHBIN(x) ( x & HASHBIN_MASK )205206/*207* Function hash (name)208*209* This function hash the input string 'name' using the ELF hash210* function for strings.211*/212static __u32 hash( const char* name)213{214__u32 h = 0;215__u32 g;216217while(*name) {218h = (h<<4) + *name++;219if ((g = (h & 0xf0000000)))220h ^=g>>24;221h &=~g;222}223return h;224}225226/*227* Function enqueue_first (queue, proc)228*229* Insert item first in queue.230*231*/232static void enqueue_first(irda_queue_t **queue, irda_queue_t* element)233{234235IRDA_DEBUG( 4, "%s()\n", __func__);236237/*238* Check if queue is empty.239*/240if ( *queue == NULL ) {241/*242* Queue is empty. Insert one element into the queue.243*/244element->q_next = element->q_prev = *queue = element;245246} else {247/*248* Queue is not empty. Insert element into front of queue.249*/250element->q_next = (*queue);251(*queue)->q_prev->q_next = element;252element->q_prev = (*queue)->q_prev;253(*queue)->q_prev = element;254(*queue) = element;255}256}257258259/*260* Function dequeue (queue)261*262* Remove first entry in queue263*264*/265static irda_queue_t *dequeue_first(irda_queue_t **queue)266{267irda_queue_t *ret;268269IRDA_DEBUG( 4, "dequeue_first()\n");270271/*272* Set return value273*/274ret = *queue;275276if ( *queue == NULL ) {277/*278* Queue was empty.279*/280} else if ( (*queue)->q_next == *queue ) {281/*282* Queue only contained a single element. It will now be283* empty.284*/285*queue = NULL;286} else {287/*288* Queue contained several element. Remove the first one.289*/290(*queue)->q_prev->q_next = (*queue)->q_next;291(*queue)->q_next->q_prev = (*queue)->q_prev;292*queue = (*queue)->q_next;293}294295/*296* Return the removed entry (or NULL of queue was empty).297*/298return ret;299}300301/*302* Function dequeue_general (queue, element)303*304*305*/306static irda_queue_t *dequeue_general(irda_queue_t **queue, irda_queue_t* element)307{308irda_queue_t *ret;309310IRDA_DEBUG( 4, "dequeue_general()\n");311312/*313* Set return value314*/315ret = *queue;316317if ( *queue == NULL ) {318/*319* Queue was empty.320*/321} else if ( (*queue)->q_next == *queue ) {322/*323* Queue only contained a single element. It will now be324* empty.325*/326*queue = NULL;327328} else {329/*330* Remove specific element.331*/332element->q_prev->q_next = element->q_next;333element->q_next->q_prev = element->q_prev;334if ( (*queue) == element)335(*queue) = element->q_next;336}337338/*339* Return the removed entry (or NULL of queue was empty).340*/341return ret;342}343344/************************ HASHBIN MANAGEMENT ************************/345346/*347* Function hashbin_create ( type, name )348*349* Create hashbin!350*351*/352hashbin_t *hashbin_new(int type)353{354hashbin_t* hashbin;355356/*357* Allocate new hashbin358*/359hashbin = kzalloc(sizeof(*hashbin), GFP_ATOMIC);360if (!hashbin)361return NULL;362363/*364* Initialize structure365*/366hashbin->hb_type = type;367hashbin->magic = HB_MAGIC;368//hashbin->hb_current = NULL;369370/* Make sure all spinlock's are unlocked */371if ( hashbin->hb_type & HB_LOCK ) {372spin_lock_init(&hashbin->hb_spinlock);373}374375return hashbin;376}377EXPORT_SYMBOL(hashbin_new);378379380/*381* Function hashbin_delete (hashbin, free_func)382*383* Destroy hashbin, the free_func can be a user supplied special routine384* for deallocating this structure if it's complex. If not the user can385* just supply kfree, which should take care of the job.386*/387#ifdef CONFIG_LOCKDEP388static int hashbin_lock_depth = 0;389#endif390int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)391{392irda_queue_t* queue;393unsigned long flags = 0;394int i;395396IRDA_ASSERT(hashbin != NULL, return -1;);397IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;);398399/* Synchronize */400if ( hashbin->hb_type & HB_LOCK ) {401spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags,402hashbin_lock_depth++);403}404405/*406* Free the entries in the hashbin, TODO: use hashbin_clear when407* it has been shown to work408*/409for (i = 0; i < HASHBIN_SIZE; i ++ ) {410queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);411while (queue ) {412if (free_func)413(*free_func)(queue);414queue = dequeue_first(415(irda_queue_t**) &hashbin->hb_queue[i]);416}417}418419/* Cleanup local data */420hashbin->hb_current = NULL;421hashbin->magic = ~HB_MAGIC;422423/* Release lock */424if ( hashbin->hb_type & HB_LOCK) {425spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);426#ifdef CONFIG_LOCKDEP427hashbin_lock_depth--;428#endif429}430431/*432* Free the hashbin structure433*/434kfree(hashbin);435436return 0;437}438EXPORT_SYMBOL(hashbin_delete);439440/********************* HASHBIN LIST OPERATIONS *********************/441442/*443* Function hashbin_insert (hashbin, entry, name)444*445* Insert an entry into the hashbin446*447*/448void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv,449const char* name)450{451unsigned long flags = 0;452int bin;453454IRDA_DEBUG( 4, "%s()\n", __func__);455456IRDA_ASSERT( hashbin != NULL, return;);457IRDA_ASSERT( hashbin->magic == HB_MAGIC, return;);458459/*460* Locate hashbin461*/462if ( name )463hashv = hash( name );464bin = GET_HASHBIN( hashv );465466/* Synchronize */467if ( hashbin->hb_type & HB_LOCK ) {468spin_lock_irqsave(&hashbin->hb_spinlock, flags);469} /* Default is no-lock */470471/*472* Store name and key473*/474entry->q_hash = hashv;475if ( name )476strlcpy( entry->q_name, name, sizeof(entry->q_name));477478/*479* Insert new entry first480*/481enqueue_first( (irda_queue_t**) &hashbin->hb_queue[ bin ],482entry);483hashbin->hb_size++;484485/* Release lock */486if ( hashbin->hb_type & HB_LOCK ) {487spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);488} /* Default is no-lock */489}490EXPORT_SYMBOL(hashbin_insert);491492/*493* Function hashbin_remove_first (hashbin)494*495* Remove first entry of the hashbin496*497* Note : this function no longer use hashbin_remove(), but does things498* similar to hashbin_remove_this(), so can be considered safe.499* Jean II500*/501void *hashbin_remove_first( hashbin_t *hashbin)502{503unsigned long flags = 0;504irda_queue_t *entry = NULL;505506/* Synchronize */507if ( hashbin->hb_type & HB_LOCK ) {508spin_lock_irqsave(&hashbin->hb_spinlock, flags);509} /* Default is no-lock */510511entry = hashbin_get_first( hashbin);512if ( entry != NULL) {513int bin;514long hashv;515/*516* Locate hashbin517*/518hashv = entry->q_hash;519bin = GET_HASHBIN( hashv );520521/*522* Dequeue the entry...523*/524dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ],525(irda_queue_t*) entry );526hashbin->hb_size--;527entry->q_next = NULL;528entry->q_prev = NULL;529530/*531* Check if this item is the currently selected item, and in532* that case we must reset hb_current533*/534if ( entry == hashbin->hb_current)535hashbin->hb_current = NULL;536}537538/* Release lock */539if ( hashbin->hb_type & HB_LOCK ) {540spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);541} /* Default is no-lock */542543return entry;544}545546547/*548* Function hashbin_remove (hashbin, hashv, name)549*550* Remove entry with the given name551*552* The use of this function is highly discouraged, because the whole553* concept behind hashbin_remove() is broken. In many cases, it's not554* possible to guarantee the unicity of the index (either hashv or name),555* leading to removing the WRONG entry.556* The only simple safe use is :557* hashbin_remove(hasbin, (int) self, NULL);558* In other case, you must think hard to guarantee unicity of the index.559* Jean II560*/561void* hashbin_remove( hashbin_t* hashbin, long hashv, const char* name)562{563int bin, found = FALSE;564unsigned long flags = 0;565irda_queue_t* entry;566567IRDA_DEBUG( 4, "%s()\n", __func__);568569IRDA_ASSERT( hashbin != NULL, return NULL;);570IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);571572/*573* Locate hashbin574*/575if ( name )576hashv = hash( name );577bin = GET_HASHBIN( hashv );578579/* Synchronize */580if ( hashbin->hb_type & HB_LOCK ) {581spin_lock_irqsave(&hashbin->hb_spinlock, flags);582} /* Default is no-lock */583584/*585* Search for entry586*/587entry = hashbin->hb_queue[ bin ];588if ( entry ) {589do {590/*591* Check for key592*/593if ( entry->q_hash == hashv ) {594/*595* Name compare too?596*/597if ( name ) {598if ( strcmp( entry->q_name, name) == 0)599{600found = TRUE;601break;602}603} else {604found = TRUE;605break;606}607}608entry = entry->q_next;609} while ( entry != hashbin->hb_queue[ bin ] );610}611612/*613* If entry was found, dequeue it614*/615if ( found ) {616dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ],617(irda_queue_t*) entry );618hashbin->hb_size--;619620/*621* Check if this item is the currently selected item, and in622* that case we must reset hb_current623*/624if ( entry == hashbin->hb_current)625hashbin->hb_current = NULL;626}627628/* Release lock */629if ( hashbin->hb_type & HB_LOCK ) {630spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);631} /* Default is no-lock */632633634/* Return */635if ( found )636return entry;637else638return NULL;639640}641EXPORT_SYMBOL(hashbin_remove);642643/*644* Function hashbin_remove_this (hashbin, entry)645*646* Remove entry with the given name647*648* In some cases, the user of hashbin can't guarantee the unicity649* of either the hashv or name.650* In those cases, using the above function is guaranteed to cause troubles,651* so we use this one instead...652* And by the way, it's also faster, because we skip the search phase ;-)653*/654void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry)655{656unsigned long flags = 0;657int bin;658long hashv;659660IRDA_DEBUG( 4, "%s()\n", __func__);661662IRDA_ASSERT( hashbin != NULL, return NULL;);663IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);664IRDA_ASSERT( entry != NULL, return NULL;);665666/* Synchronize */667if ( hashbin->hb_type & HB_LOCK ) {668spin_lock_irqsave(&hashbin->hb_spinlock, flags);669} /* Default is no-lock */670671/* Check if valid and not already removed... */672if((entry->q_next == NULL) || (entry->q_prev == NULL)) {673entry = NULL;674goto out;675}676677/*678* Locate hashbin679*/680hashv = entry->q_hash;681bin = GET_HASHBIN( hashv );682683/*684* Dequeue the entry...685*/686dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ],687(irda_queue_t*) entry );688hashbin->hb_size--;689entry->q_next = NULL;690entry->q_prev = NULL;691692/*693* Check if this item is the currently selected item, and in694* that case we must reset hb_current695*/696if ( entry == hashbin->hb_current)697hashbin->hb_current = NULL;698out:699/* Release lock */700if ( hashbin->hb_type & HB_LOCK ) {701spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);702} /* Default is no-lock */703704return entry;705}706EXPORT_SYMBOL(hashbin_remove_this);707708/*********************** HASHBIN ENUMERATION ***********************/709710/*711* Function hashbin_common_find (hashbin, hashv, name)712*713* Find item with the given hashv or name714*715*/716void* hashbin_find( hashbin_t* hashbin, long hashv, const char* name )717{718int bin;719irda_queue_t* entry;720721IRDA_DEBUG( 4, "hashbin_find()\n");722723IRDA_ASSERT( hashbin != NULL, return NULL;);724IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);725726/*727* Locate hashbin728*/729if ( name )730hashv = hash( name );731bin = GET_HASHBIN( hashv );732733/*734* Search for entry735*/736entry = hashbin->hb_queue[ bin];737if ( entry ) {738do {739/*740* Check for key741*/742if ( entry->q_hash == hashv ) {743/*744* Name compare too?745*/746if ( name ) {747if ( strcmp( entry->q_name, name ) == 0 ) {748return entry;749}750} else {751return entry;752}753}754entry = entry->q_next;755} while ( entry != hashbin->hb_queue[ bin ] );756}757758return NULL;759}760EXPORT_SYMBOL(hashbin_find);761762/*763* Function hashbin_lock_find (hashbin, hashv, name)764*765* Find item with the given hashv or name766*767* Same, but with spinlock protection...768* I call it safe, but it's only safe with respect to the hashbin, not its769* content. - Jean II770*/771void* hashbin_lock_find( hashbin_t* hashbin, long hashv, const char* name )772{773unsigned long flags = 0;774irda_queue_t* entry;775776/* Synchronize */777spin_lock_irqsave(&hashbin->hb_spinlock, flags);778779/*780* Search for entry781*/782entry = (irda_queue_t* ) hashbin_find( hashbin, hashv, name );783784/* Release lock */785spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);786787return entry;788}789EXPORT_SYMBOL(hashbin_lock_find);790791/*792* Function hashbin_find (hashbin, hashv, name, pnext)793*794* Find an item with the given hashv or name, and its successor795*796* This function allow to do concurrent enumerations without the797* need to lock over the whole session, because the caller keep the798* context of the search. On the other hand, it might fail and return799* NULL if the entry is removed. - Jean II800*/801void* hashbin_find_next( hashbin_t* hashbin, long hashv, const char* name,802void ** pnext)803{804unsigned long flags = 0;805irda_queue_t* entry;806807/* Synchronize */808spin_lock_irqsave(&hashbin->hb_spinlock, flags);809810/*811* Search for current entry812* This allow to check if the current item is still in the813* hashbin or has been removed.814*/815entry = (irda_queue_t* ) hashbin_find( hashbin, hashv, name );816817/*818* Trick hashbin_get_next() to return what we want819*/820if(entry) {821hashbin->hb_current = entry;822*pnext = hashbin_get_next( hashbin );823} else824*pnext = NULL;825826/* Release lock */827spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);828829return entry;830}831832/*833* Function hashbin_get_first (hashbin)834*835* Get a pointer to first element in hashbin, this function must be836* called before any calls to hashbin_get_next()!837*838*/839irda_queue_t *hashbin_get_first( hashbin_t* hashbin)840{841irda_queue_t *entry;842int i;843844IRDA_ASSERT( hashbin != NULL, return NULL;);845IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);846847if ( hashbin == NULL)848return NULL;849850for ( i = 0; i < HASHBIN_SIZE; i ++ ) {851entry = hashbin->hb_queue[ i];852if ( entry) {853hashbin->hb_current = entry;854return entry;855}856}857/*858* Did not find any item in hashbin859*/860return NULL;861}862EXPORT_SYMBOL(hashbin_get_first);863864/*865* Function hashbin_get_next (hashbin)866*867* Get next item in hashbin. A series of hashbin_get_next() calls must868* be started by a call to hashbin_get_first(). The function returns869* NULL when all items have been traversed870*871* The context of the search is stored within the hashbin, so you must872* protect yourself from concurrent enumerations. - Jean II873*/874irda_queue_t *hashbin_get_next( hashbin_t *hashbin)875{876irda_queue_t* entry;877int bin;878int i;879880IRDA_ASSERT( hashbin != NULL, return NULL;);881IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);882883if ( hashbin->hb_current == NULL) {884IRDA_ASSERT( hashbin->hb_current != NULL, return NULL;);885return NULL;886}887entry = hashbin->hb_current->q_next;888bin = GET_HASHBIN( entry->q_hash);889890/*891* Make sure that we are not back at the beginning of the queue892* again893*/894if ( entry != hashbin->hb_queue[ bin ]) {895hashbin->hb_current = entry;896897return entry;898}899900/*901* Check that this is not the last queue in hashbin902*/903if ( bin >= HASHBIN_SIZE)904return NULL;905906/*907* Move to next queue in hashbin908*/909bin++;910for ( i = bin; i < HASHBIN_SIZE; i++ ) {911entry = hashbin->hb_queue[ i];912if ( entry) {913hashbin->hb_current = entry;914915return entry;916}917}918return NULL;919}920EXPORT_SYMBOL(hashbin_get_next);921922923