Lines Matching refs:lc

29 	BUG_ON(!lc);			\
30 BUG_ON(!lc->nr_elements); \
31 BUG_ON(test_and_set_bit(__LC_PARANOIA, &lc->flags)); \
35 clear_bit_unlock(__LC_PARANOIA, &lc->flags); \
39 #define PARANOIA_LC_ELEMENT(lc, e) do { \ argument
40 struct lru_cache *lc_ = (lc); \
55 int lc_try_lock(struct lru_cache *lc) in lc_try_lock() argument
59 val = cmpxchg(&lc->flags, 0, LC_LOCKED); in lc_try_lock()
83 struct lru_cache *lc; in lc_create() local
104 lc = kzalloc(sizeof(*lc), GFP_KERNEL); in lc_create()
105 if (!lc) in lc_create()
108 INIT_LIST_HEAD(&lc->in_use); in lc_create()
109 INIT_LIST_HEAD(&lc->lru); in lc_create()
110 INIT_LIST_HEAD(&lc->free); in lc_create()
111 INIT_LIST_HEAD(&lc->to_be_changed); in lc_create()
113 lc->name = name; in lc_create()
114 lc->element_size = e_size; in lc_create()
115 lc->element_off = e_off; in lc_create()
116 lc->nr_elements = e_count; in lc_create()
117 lc->max_pending_changes = max_pending_changes; in lc_create()
118 lc->lc_cache = cache; in lc_create()
119 lc->lc_element = element; in lc_create()
120 lc->lc_slot = slot; in lc_create()
127 memset(p, 0, lc->element_size); in lc_create()
132 list_add(&e->list, &lc->free); in lc_create()
136 return lc; in lc_create()
143 kfree(lc); in lc_create()
150 static void lc_free_by_index(struct lru_cache *lc, unsigned i) in lc_free_by_index() argument
152 void *p = lc->lc_element[i]; in lc_free_by_index()
155 p -= lc->element_off; in lc_free_by_index()
156 kmem_cache_free(lc->lc_cache, p); in lc_free_by_index()
164 void lc_destroy(struct lru_cache *lc) in lc_destroy() argument
167 if (!lc) in lc_destroy()
169 for (i = 0; i < lc->nr_elements; i++) in lc_destroy()
170 lc_free_by_index(lc, i); in lc_destroy()
171 kfree(lc->lc_element); in lc_destroy()
172 kfree(lc->lc_slot); in lc_destroy()
173 kfree(lc); in lc_destroy()
183 void lc_reset(struct lru_cache *lc) in lc_reset() argument
187 INIT_LIST_HEAD(&lc->in_use); in lc_reset()
188 INIT_LIST_HEAD(&lc->lru); in lc_reset()
189 INIT_LIST_HEAD(&lc->free); in lc_reset()
190 INIT_LIST_HEAD(&lc->to_be_changed); in lc_reset()
191 lc->used = 0; in lc_reset()
192 lc->hits = 0; in lc_reset()
193 lc->misses = 0; in lc_reset()
194 lc->starving = 0; in lc_reset()
195 lc->locked = 0; in lc_reset()
196 lc->changed = 0; in lc_reset()
197 lc->pending_changes = 0; in lc_reset()
198 lc->flags = 0; in lc_reset()
199 memset(lc->lc_slot, 0, sizeof(struct hlist_head) * lc->nr_elements); in lc_reset()
201 for (i = 0; i < lc->nr_elements; i++) { in lc_reset()
202 struct lc_element *e = lc->lc_element[i]; in lc_reset()
204 p -= lc->element_off; in lc_reset()
205 memset(p, 0, lc->element_size); in lc_reset()
210 list_add(&e->list, &lc->free); in lc_reset()
219 void lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc) in lc_seq_printf_stats() argument
229 lc->name, lc->used, lc->nr_elements, in lc_seq_printf_stats()
230 lc->hits, lc->misses, lc->starving, lc->locked, lc->changed); in lc_seq_printf_stats()
233 static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) in lc_hash_slot() argument
235 return lc->lc_slot + (enr % lc->nr_elements); in lc_hash_slot()
239 static struct lc_element *__lc_find(struct lru_cache *lc, unsigned int enr, in __lc_find() argument
244 BUG_ON(!lc); in __lc_find()
245 BUG_ON(!lc->nr_elements); in __lc_find()
246 hlist_for_each_entry(e, lc_hash_slot(lc, enr), colision) { in __lc_find()
270 struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr) in lc_find() argument
272 return __lc_find(lc, enr, 0); in lc_find()
285 bool lc_is_used(struct lru_cache *lc, unsigned int enr) in lc_is_used() argument
287 struct lc_element *e = __lc_find(lc, enr, 1); in lc_is_used()
299 void lc_del(struct lru_cache *lc, struct lc_element *e) in lc_del() argument
302 PARANOIA_LC_ELEMENT(lc, e); in lc_del()
307 list_move(&e->list, &lc->free); in lc_del()
311 static struct lc_element *lc_prepare_for_change(struct lru_cache *lc, unsigned new_number) in lc_prepare_for_change() argument
316 if (!list_empty(&lc->free)) in lc_prepare_for_change()
317 n = lc->free.next; in lc_prepare_for_change()
318 else if (!list_empty(&lc->lru)) in lc_prepare_for_change()
319 n = lc->lru.prev; in lc_prepare_for_change()
324 PARANOIA_LC_ELEMENT(lc, e); in lc_prepare_for_change()
329 hlist_add_head(&e->colision, lc_hash_slot(lc, new_number)); in lc_prepare_for_change()
330 list_move(&e->list, &lc->to_be_changed); in lc_prepare_for_change()
335 static int lc_unused_element_available(struct lru_cache *lc) in lc_unused_element_available() argument
337 if (!list_empty(&lc->free)) in lc_unused_element_available()
339 if (!list_empty(&lc->lru)) in lc_unused_element_available()
351 static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, unsigned int flags) in __lc_get() argument
356 if (test_bit(__LC_STARVING, &lc->flags)) { in __lc_get()
357 ++lc->starving; in __lc_get()
361 e = __lc_find(lc, enr, 1); in __lc_get()
377 ++lc->hits; in __lc_get()
381 ++lc->hits; in __lc_get()
383 lc->used++; in __lc_get()
384 list_move(&e->list, &lc->in_use); /* Not evictable... */ in __lc_get()
389 ++lc->misses; in __lc_get()
395 test_and_set_bit(__LC_DIRTY, &lc->flags); in __lc_get()
400 if (test_bit(__LC_LOCKED, &lc->flags)) { in __lc_get()
401 ++lc->locked; in __lc_get()
408 if (!lc_unused_element_available(lc)) { in __lc_get()
409 set_bit(__LC_STARVING, &lc->flags); in __lc_get()
416 if (lc->pending_changes >= lc->max_pending_changes) in __lc_get()
419 e = lc_prepare_for_change(lc, enr); in __lc_get()
422 clear_bit(__LC_STARVING, &lc->flags); in __lc_get()
424 lc->used++; in __lc_get()
425 lc->pending_changes++; in __lc_get()
470 struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) in lc_get() argument
472 return __lc_get(lc, enr, LC_GET_MAY_CHANGE); in lc_get()
490 struct lc_element *lc_get_cumulative(struct lru_cache *lc, unsigned int enr) in lc_get_cumulative() argument
492 return __lc_get(lc, enr, LC_GET_MAY_CHANGE|LC_GET_MAY_USE_UNCOMMITTED); in lc_get_cumulative()
511 struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr) in lc_try_get() argument
513 return __lc_get(lc, enr, 0); in lc_try_get()
524 void lc_committed(struct lru_cache *lc) in lc_committed() argument
529 list_for_each_entry_safe(e, tmp, &lc->to_be_changed, list) { in lc_committed()
531 ++lc->changed; in lc_committed()
533 list_move(&e->list, &lc->in_use); in lc_committed()
535 lc->pending_changes = 0; in lc_committed()
549 unsigned int lc_put(struct lru_cache *lc, struct lc_element *e) in lc_put() argument
552 PARANOIA_LC_ELEMENT(lc, e); in lc_put()
557 list_move(&e->list, &lc->lru); in lc_put()
558 lc->used--; in lc_put()
559 clear_bit_unlock(__LC_STARVING, &lc->flags); in lc_put()
569 struct lc_element *lc_element_by_index(struct lru_cache *lc, unsigned i) in lc_element_by_index() argument
571 BUG_ON(i >= lc->nr_elements); in lc_element_by_index()
572 BUG_ON(lc->lc_element[i] == NULL); in lc_element_by_index()
573 BUG_ON(lc->lc_element[i]->lc_index != i); in lc_element_by_index()
574 return lc->lc_element[i]; in lc_element_by_index()
586 void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext, in lc_seq_dump_details() argument
589 unsigned int nr_elements = lc->nr_elements; in lc_seq_dump_details()
595 e = lc_element_by_index(lc, i); in lc_seq_dump_details()