执行:echo 3 > /proc/sys/vm/drop_caches
内核入口:
fs/drop_caches.c
drop_caches_sysctl_handler()
如果bit 1设置了,1或3。则表示清空page cache。
为每个super block,调用下面的函数。
static void drop_pagecache_sb(struct super_block *sb, void *unused)
它遍历sb->s_inodes,也就是所有的inode节点,对于可以释放的节点,执行:
invalidate_mapping_pages(inode->i_mapping, 0, -1);
如果bit 2设置了,2或者3,表示清空未用的dentry和inode。
调用drop_slab()
调用栈:
[ 70.415609] CPU: 1 UID: 0 PID: 121 Comm: ash Not tainted 6.12.37+ #8 [ 70.415631] Hardware name: linux,dummy-virt (DT) [ 70.415636] Call trace: [ 70.415639] dump_backtrace+0xac/0xcc [ 70.415655] show_stack+0x14/0x1c [ 70.415663] dump_stack_lvl+0x78/0xa8 [ 70.415670] dump_stack+0x14/0x1c [ 70.415676] dentry_free+0x30/0xa8 [ 70.415684] __dentry_kill+0x194/0x198 [ 70.415690] shrink_kill+0x1c/0xa0 [ 70.415696] shrink_dentry_list+0xdc/0xe0 [ 70.415702] prune_dcache_sb+0x40/0x50 [ 70.415708] super_cache_scan+0xdc/0x13c [ 70.415715] shrink_slab+0x2e0/0x498 [ 70.415721] drop_slab+0x34/0x58 [ 70.415729] drop_caches_sysctl_handler+0x50/0xa0 [ 70.415736] proc_sys_call_handler+0x130/0x194 [ 70.415744] proc_sys_write+0x10/0x18 [ 70.415752] vfs_write+0x110/0x158 [ 70.415760] ksys_write+0x64/0xac [ 70.415765] __arm64_sys_write+0x14/0x1c [ 70.415771] do_el0_svc+0xa8/0xd0 [ 70.415777] el0_svc+0x34/0x8c [ 70.415785] el0t_64_sync_handler+0x80/0x124 [ 70.415792] el0t_64_sync+0x14c/0x150 [ 70.416409] ash (121): drop_caches: 3
解释,super block会分配、注册shrinker.
见fs/super.c alloc_super()
shrinker的动作函数是:super_cache_scan()
这个函数又会调用
prune_dcache_sb()
prune_icache_sb()
释放dcache和icache。
dcache的lru list是:sb->s_dentry_lru
icache的lru list是:sb->s_inode_lru