mm/shrinker.c
Source file repositories/reference/linux-study-clean/mm/shrinker.c
File Facts
- System
- Linux kernel
- Corpus path
mm/shrinker.c- Extension
.c- Size
- 22021 bytes
- Lines
- 814
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/memcontrol.hlinux/rwsem.hlinux/shrinker.hlinux/rculist.htrace/events/vmscan.hinternal.h
Detected Declarations
function shrinker_unit_sizefunction shrinker_unit_freefunction shrinker_unit_allocfunction free_shrinker_infofunction for_each_nodefunction alloc_shrinker_infofunction expand_one_shrinker_infofunction for_each_nodefunction expand_shrinker_infofunction shrinker_id_to_indexfunction shrinker_id_to_offsetfunction calc_shrinker_idfunction set_shrinker_bitfunction shrinker_memcg_allocfunction shrinker_memcg_removefunction xchg_nr_deferred_memcgfunction add_nr_deferred_memcgfunction reparent_shrinker_deferredfunction shrinker_memcg_allocfunction shrinker_memcg_removefunction add_nr_deferred_memcgfunction xchg_nr_deferredfunction add_nr_deferredfunction do_shrink_slabfunction scanfunction shrink_slab_memcgfunction for_each_set_bitfunction shrink_slab_memcgfunction shrink_slabfunction shrinker_registerfunction shrinker_free_rcu_cbfunction shrinker_freeexport shrinker_allocexport shrinker_registerexport shrinker_free
Annotated Snippet
if (!unit) {
shrinker_unit_free(new, start);
return -ENOMEM;
}
new->unit[i] = unit;
}
return 0;
}
void free_shrinker_info(struct mem_cgroup *memcg)
{
struct mem_cgroup_per_node *pn;
struct shrinker_info *info;
int nid;
for_each_node(nid) {
pn = memcg->nodeinfo[nid];
info = rcu_dereference_protected(pn->shrinker_info, true);
shrinker_unit_free(info, 0);
kvfree(info);
rcu_assign_pointer(pn->shrinker_info, NULL);
}
}
int alloc_shrinker_info(struct mem_cgroup *memcg)
{
int nid, ret = 0;
int array_size = 0;
mutex_lock(&shrinker_mutex);
array_size = shrinker_unit_size(shrinker_nr_max);
for_each_node(nid) {
struct shrinker_info *info = kvzalloc_node(sizeof(*info) + array_size,
GFP_KERNEL, nid);
if (!info)
goto err;
info->map_nr_max = shrinker_nr_max;
if (shrinker_unit_alloc(info, NULL, nid)) {
kvfree(info);
goto err;
}
rcu_assign_pointer(memcg->nodeinfo[nid]->shrinker_info, info);
}
mutex_unlock(&shrinker_mutex);
return ret;
err:
mutex_unlock(&shrinker_mutex);
free_shrinker_info(memcg);
return -ENOMEM;
}
static struct shrinker_info *shrinker_info_protected(struct mem_cgroup *memcg,
int nid)
{
return rcu_dereference_protected(memcg->nodeinfo[nid]->shrinker_info,
lockdep_is_held(&shrinker_mutex));
}
static int expand_one_shrinker_info(struct mem_cgroup *memcg, int new_size,
int old_size, int new_nr_max)
{
struct shrinker_info *new, *old;
struct mem_cgroup_per_node *pn;
int nid;
for_each_node(nid) {
pn = memcg->nodeinfo[nid];
old = shrinker_info_protected(memcg, nid);
/* Not yet online memcg */
if (!old)
return 0;
/* Already expanded this shrinker_info */
if (new_nr_max <= old->map_nr_max)
continue;
new = kvzalloc_node(sizeof(*new) + new_size, GFP_KERNEL, nid);
if (!new)
return -ENOMEM;
new->map_nr_max = new_nr_max;
memcpy(new->unit, old->unit, old_size);
if (shrinker_unit_alloc(new, old, nid)) {
kvfree(new);
return -ENOMEM;
Annotation
- Immediate include surface: `linux/memcontrol.h`, `linux/rwsem.h`, `linux/shrinker.h`, `linux/rculist.h`, `trace/events/vmscan.h`, `internal.h`.
- Detected declarations: `function shrinker_unit_size`, `function shrinker_unit_free`, `function shrinker_unit_alloc`, `function free_shrinker_info`, `function for_each_node`, `function alloc_shrinker_info`, `function expand_one_shrinker_info`, `function for_each_node`, `function expand_shrinker_info`, `function shrinker_id_to_index`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.