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); \
38 /* BUG() if e is not one of the elements tracked by lc */
39 #define PARANOIA_LC_ELEMENT(lc, e) do { \
40 struct lru_cache *lc_ = (lc); \
51 * Because of PARANOIA_ENTRY() above abusing lc->flags as well,
53 * return 0 == cmpxchg(&lc->flags, 0, LC_LOCKED);
55 int lc_try_lock(struct lru_cache *lc)
59 val = cmpxchg(&lc->flags, 0, LC_LOCKED);
83 struct lru_cache *lc;
104 lc = kzalloc(sizeof(*lc), GFP_KERNEL);
105 if (!lc)
108 INIT_LIST_HEAD(&lc->in_use);
109 INIT_LIST_HEAD(&lc->lru);
110 INIT_LIST_HEAD(&lc->free);
111 INIT_LIST_HEAD(&lc->to_be_changed);
113 lc->name = name;
114 lc->element_size = e_size;
115 lc->element_off = e_off;
116 lc->nr_elements = e_count;
117 lc->max_pending_changes = max_pending_changes;
118 lc->lc_cache = cache;
119 lc->lc_element = element;
120 lc->lc_slot = slot;
127 memset(p, 0, lc->element_size);
132 list_add(&e->list, &lc->free);
136 return lc;
143 kfree(lc);
150 static void lc_free_by_index(struct lru_cache *lc, unsigned i)
152 void *p = lc->lc_element[i];
155 p -= lc->element_off;
156 kmem_cache_free(lc->lc_cache, p);
162 * @lc: the lru cache to destroy
164 void lc_destroy(struct lru_cache *lc)
167 if (!lc)
169 for (i = 0; i < lc->nr_elements; i++)
170 lc_free_by_index(lc, i);
171 kfree(lc->lc_element);
172 kfree(lc->lc_slot);
173 kfree(lc);
177 * lc_reset - does a full reset for @lc and the hash table slots.
178 * @lc: the lru cache to operate on
181 * basically a short cut to lc_destroy(lc); lc = lc_create(...);
183 void lc_reset(struct lru_cache *lc)
187 INIT_LIST_HEAD(&lc->in_use);
188 INIT_LIST_HEAD(&lc->lru);
189 INIT_LIST_HEAD(&lc->free);
190 INIT_LIST_HEAD(&lc->to_be_changed);
191 lc->used = 0;
192 lc->hits = 0;
193 lc->misses = 0;
194 lc->starving = 0;
195 lc->locked = 0;
196 lc->changed = 0;
197 lc->pending_changes = 0;
198 lc->flags = 0;
199 memset(lc->lc_slot, 0, sizeof(struct hlist_head) * lc->nr_elements);
201 for (i = 0; i < lc->nr_elements; i++) {
202 struct lc_element *e = lc->lc_element[i];
204 p -= lc->element_off;
205 memset(p, 0, lc->element_size);
210 list_add(&e->list, &lc->free);
215 * lc_seq_printf_stats - print stats about @lc into @seq
217 * @lc: the lru cache to print statistics of
219 void lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc)
229 lc->name, lc->used, lc->nr_elements,
230 lc->hits, lc->misses, lc->starving, lc->locked, lc->changed);
233 static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr)
235 return lc->lc_slot + (enr % lc->nr_elements);
239 static struct lc_element *__lc_find(struct lru_cache *lc, unsigned int enr,
244 BUG_ON(!lc);
245 BUG_ON(!lc->nr_elements);
246 hlist_for_each_entry(e, lc_hash_slot(lc, enr), colision) {
261 * @lc: The lru_cache object
270 struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr)
272 return __lc_find(lc, enr, 0);
277 * @lc: The lru_cache object
285 bool lc_is_used(struct lru_cache *lc, unsigned int enr)
287 struct lc_element *e = __lc_find(lc, enr, 1);
293 * @lc: The lru_cache object
299 void lc_del(struct lru_cache *lc, struct lc_element *e)
302 PARANOIA_LC_ELEMENT(lc, e);
307 list_move(&e->list, &lc->free);
311 static struct lc_element *lc_prepare_for_change(struct lru_cache *lc, unsigned new_number)
316 if (!list_empty(&lc->free))
317 n = lc->free.next;
318 else if (!list_empty(&lc->lru))
319 n = lc->lru.prev;
324 PARANOIA_LC_ELEMENT(lc, e);
329 hlist_add_head(&e->colision, lc_hash_slot(lc, new_number));
330 list_move(&e->list, &lc->to_be_changed);
335 static int lc_unused_element_available(struct lru_cache *lc)
337 if (!list_empty(&lc->free))
339 if (!list_empty(&lc->lru))
351 static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, unsigned int flags)
356 if (test_bit(__LC_STARVING, &lc->flags)) {
357 ++lc->starving;
361 e = __lc_find(lc, enr, 1);
377 ++lc->hits;
381 ++lc->hits;
383 lc->used++;
384 list_move(&e->list, &lc->in_use); /* Not evictable... */
389 ++lc->misses;
395 test_and_set_bit(__LC_DIRTY, &lc->flags);
400 if (test_bit(__LC_LOCKED, &lc->flags)) {
401 ++lc->locked;
408 if (!lc_unused_element_available(lc)) {
409 set_bit(__LC_STARVING, &lc->flags);
416 if (lc->pending_changes >= lc->max_pending_changes)
419 e = lc_prepare_for_change(lc, enr);
422 clear_bit(__LC_STARVING, &lc->flags);
424 lc->used++;
425 lc->pending_changes++;
432 * @lc: the lru cache to operate on
447 * and a changing transaction is still pending (@lc was marked %LC_DIRTY).
448 * Or no unused or free element could be recycled (@lc will be marked as
465 * lc_committed(lc) and lc_unlock(), to finish the change.
470 struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr)
472 return __lc_get(lc, enr, LC_GET_MAY_CHANGE);
477 * @lc: the lru cache to operate on
490 struct lc_element *lc_get_cumulative(struct lru_cache *lc, unsigned int enr)
492 return __lc_get(lc, enr, LC_GET_MAY_CHANGE|LC_GET_MAY_USE_UNCOMMITTED);
497 * @lc: the lru cache to operate on
511 struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr)
513 return __lc_get(lc, enr, 0);
517 * lc_committed - tell @lc that pending changes have been recorded
518 * @lc: the lru cache to operate on
524 void lc_committed(struct lru_cache *lc)
529 list_for_each_entry_safe(e, tmp, &lc->to_be_changed, list) {
531 ++lc->changed;
533 list_move(&e->list, &lc->in_use);
535 lc->pending_changes = 0;
542 * @lc: the lru cache to operate on
549 unsigned int lc_put(struct lru_cache *lc, struct lc_element *e)
552 PARANOIA_LC_ELEMENT(lc, e);
557 list_move(&e->list, &lc->lru);
558 lc->used--;
559 clear_bit_unlock(__LC_STARVING, &lc->flags);
566 * @lc: the lru cache to operate on
569 struct lc_element *lc_element_by_index(struct lru_cache *lc, unsigned i)
571 BUG_ON(i >= lc->nr_elements);
572 BUG_ON(lc->lc_element[i] == NULL);
573 BUG_ON(lc->lc_element[i]->lc_index != i);
574 return lc->lc_element[i];
579 * @lc: the lru cache to operate on
586 void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext,
589 unsigned int nr_elements = lc->nr_elements;
595 e = lc_element_by_index(lc, i);