lib/lru_cache.c
Source file repositories/reference/linux-study-clean/lib/lru_cache.c
File Facts
- System
- Linux kernel
- Corpus path
lib/lru_cache.c- Extension
.c- Size
- 17873 bytes
- Lines
- 623
- Domain
- Kernel Services
- Bucket
- lib
- Inferred role
- Kernel Services: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/bitops.hlinux/slab.hlinux/string.hlinux/seq_file.hlinux/lru_cache.h
Detected Declarations
function lc_try_lockfunction onfunction lc_free_by_indexfunction lc_destroyfunction lc_resetfunction lc_seq_printf_statsfunction lc_is_usedfunction lc_delfunction lc_unused_element_availablefunction pendingfunction lc_try_lock_for_transactionfunction newfunction lc_seq_dump_detailsexport lc_createexport lc_resetexport lc_destroyexport lc_delexport lc_try_getexport lc_findexport lc_getexport lc_putexport lc_committedexport lc_element_by_indexexport lc_seq_printf_statsexport lc_seq_dump_detailsexport lc_try_lockexport lc_is_usedexport lc_get_cumulative
Annotated Snippet
if (e->lc_new_number != e->lc_number) {
/* It has been found above, but on the "to_be_changed"
* list, not yet committed. Don't pull it in twice,
* wait for the transaction, then try again...
*/
if (!(flags & LC_GET_MAY_USE_UNCOMMITTED))
RETURN(NULL);
/* ... unless the caller is aware of the implications,
* probably preparing a cumulative transaction. */
++e->refcnt;
++lc->hits;
RETURN(e);
}
/* else: lc_new_number == lc_number; a real hit. */
++lc->hits;
if (e->refcnt++ == 0)
lc->used++;
list_move(&e->list, &lc->in_use); /* Not evictable... */
RETURN(e);
}
/* e == NULL */
++lc->misses;
if (!(flags & LC_GET_MAY_CHANGE))
RETURN(NULL);
/* To avoid races with lc_try_lock(), first, mark us dirty
* (using test_and_set_bit, as it implies memory barriers), ... */
test_and_set_bit(__LC_DIRTY, &lc->flags);
/* ... only then check if it is locked anyways. If lc_unlock clears
* the dirty bit again, that's not a problem, we will come here again.
*/
if (test_bit(__LC_LOCKED, &lc->flags)) {
++lc->locked;
RETURN(NULL);
}
/* In case there is nothing available and we can not kick out
* the LRU element, we have to wait ...
*/
if (!lc_unused_element_available(lc)) {
set_bit(__LC_STARVING, &lc->flags);
RETURN(NULL);
}
/* It was not present in the active set. We are going to recycle an
* unused (or even "free") element, but we won't accumulate more than
* max_pending_changes changes. */
if (lc->pending_changes >= lc->max_pending_changes)
RETURN(NULL);
e = lc_prepare_for_change(lc, enr);
BUG_ON(!e);
clear_bit(__LC_STARVING, &lc->flags);
BUG_ON(++e->refcnt != 1);
lc->used++;
lc->pending_changes++;
RETURN(e);
}
/**
* lc_get - get element by label, maybe change the active set
* @lc: the lru cache to operate on
* @enr: the label to look up
*
* Finds an element in the cache, increases its usage count,
* "touches" and returns it.
*
* In case the requested number is not present, it needs to be added to the
* cache. Therefore it is possible that an other element becomes evicted from
* the cache. In either case, the user is notified so he is able to e.g. keep
* a persistent log of the cache changes, and therefore the objects in use.
*
* Return values:
* NULL
* The cache was marked %LC_STARVING,
* or the requested label was not in the active set
* and a changing transaction is still pending (@lc was marked %LC_DIRTY).
* Or no unused or free element could be recycled (@lc will be marked as
* %LC_STARVING, blocking further lc_get() operations).
*
* pointer to the element with the REQUESTED element number.
* In this case, it can be used right away
*
* pointer to an UNUSED element with some different element number,
* where that different number may also be %LC_FREE.
*
Annotation
- Immediate include surface: `linux/module.h`, `linux/bitops.h`, `linux/slab.h`, `linux/string.h`, `linux/seq_file.h`, `linux/lru_cache.h`.
- Detected declarations: `function lc_try_lock`, `function on`, `function lc_free_by_index`, `function lc_destroy`, `function lc_reset`, `function lc_seq_printf_stats`, `function lc_is_used`, `function lc_del`, `function lc_unused_element_available`, `function pending`.
- Atlas domain: Kernel Services / lib.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.