/* this defines an element in a tracked set *.collisionisforhashtablelookup. *WhenweprocessanewIOrequest,weknowitssector,thuscandeducethe *regionnumber(label)easily.Todothelabel->objectlookupwithouta *fulllistwalk,weuseasimplehashtable. * *.listisononeofthreelists: *in_use:currentlyinuse(refcnt>0,lc_number!=LC_FREE) *lru:unusedbutreadytobereusedorrecycled *(lc_refcnt==0,lc_number!=LC_FREE), *free:unusedbutreadytoberecycled *(lc_refcnt==0,lc_number==LC_FREE), * *anelementissaidtobe"intheactiveset", *ifeitheron"in_use"or"lru",i.e.lc_number!=LC_FREE. * *DRBDcurrently(May2009)onlyuses61elementsontheresynclru_cache *(totalmemoryusage2pages),andupto3833elementsontheact_log *lru_cache,totalling~215kBfor64bitarchitecture,~53pages. * *Weusuallydonotactuallyfreetheseobjectsagain,butonly"recycle" *them,asthechange"index:-old_label,+LC_FREE"wouldneedatransaction *aswell.Whichalsomeansthatusingakmem_cachetoallocatetheobjects *fromwastessomeresources. *Butitavoidshighorderpageallocationsinkmalloc.
*/ struct lc_element { struct hlist_node collision; struct list_head list; /* LRU list or free list */ unsigned refcnt; /* back "pointer" into lc_cache->element[index],
* for paranoia, and for "lc_element_to_index" */ unsigned lc_index; /* if we want to track a larger set of objects,
* it needs to become an architecture independent u64 */ unsigned lc_number; /* special label when on free list */ #define LC_FREE (~0U)
/* for pending changes */ unsigned lc_new_number;
};
struct lru_cache { /* the least recently used item is kept at lru->prev */ struct list_head lru; struct list_head free; struct list_head in_use; struct list_head to_be_changed;
/* the pre-created kmem cache to allocate the objects from */ struct kmem_cache *lc_cache;
/* size of tracked objects, used to memset(,0,) them in lc_reset */
size_t element_size; /* offset of struct lc_element member in the tracked object */
size_t element_off;
/* number of elements (indices) */ unsignedint nr_elements; /* Arbitrary limit on maximum tracked objects. Practical limit is much *lowerduetoallocationfailures,probably.Fortypicalusecases, *nr_elementsshouldbeafewthousandatmost. *Thisalsolimitsthemaximumvalueoflc_element.lc_index,allowingthe
* 8 high bits of .lc_index to be overloaded with flags in the future. */ #define LC_MAX_ACTIVE (1<<24)
/* allow to accumulate a few (index:label) changes,
* but no more than max_pending_changes */ unsignedint max_pending_changes; /* number of elements currently on to_be_changed list */ unsignedint pending_changes;
/* statistics */ unsigned used; /* number of elements currently on in_use list */ unsignedlong hits, misses, starving, locked, changed;
/* see below: flag-bits for lru_cache */ unsignedlong flags;
/* flag-bits for lru_cache */ enum { /* debugging aid, to catch concurrent access early.
* user needs to guarantee exclusive access by proper locking! */
__LC_PARANOIA,
/* annotate that the set is "dirty", possibly accumulating further
* changes, until a transaction is finally triggered */
__LC_DIRTY,
/* Locked, no further changes allowed.
* Also used to serialize changing transactions. */
__LC_LOCKED,
/* if we need to change the set, but currently there is no free nor *unusedelementavailable,weare"starving",andmustnotgiveout *furtherreferences,toguaranteethateventuallysomerefcntwill *droptozeroandwewillbeabletomakeprogressagain,changing *theset,writingthetransaction. *ifthestatisticssaywearefrequentlystarving,
* nr_elements is too small. */
__LC_STARVING,
}; #define LC_PARANOIA (1<<__LC_PARANOIA) #define LC_DIRTY (1<<__LC_DIRTY) #define LC_LOCKED (1<<__LC_LOCKED) #define LC_STARVING (1<<__LC_STARVING)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.