内存管理-34-内存回收-shrinker的注册和调用

基于msm-5.4


一、简介

当存在内存压力时,会调用 shrinker 的 count_objects() 和 scan_objects() 进程内存回收操作。


二、注册逻辑

1. 注册

ashmem_init //ashmem.c
    register_shrinker(&ashmem_shrinker) //vmscan.c
        register_shrinker_prepared(shrinker)
            list_add_tail(&shrinker->list, &shrinker_list);


2. 取消注册

unregister_shrinker(struct shrinker *shrinker)
    if (shrinker->flags & SHRINKER_MEMCG_AWARE)
        unregister_memcg_shrinker(shrinker)
            idr_remove(&shrinker_idr, shrinker->id); //memcg的使用的是idr
    list_del(&shrinker->list); //直接从链表上删除

注册就是挂入到全局 shrinker_list 链表上。


三、shrinker回调调用路径

1. 调用路径梳理

复制代码
                                /proc/sys/vm/drop_caches //sysctl.c 【】用户接口
                                    drop_caches_sysctl_handler //drop_caches.c 参数bit1=1为1才执行
                                        drop_slab //vmscan.c
                                            drop_slab_node //vmscan.c TODO
                    __alloc_pages_slowpath //page_alloc.c 【】内存分配慢速路径
                        __alloc_pages_direct_reclaim //page_alloc.c
                            __perform_reclaim //page_alloc.c
                                try_to_free_pages //vmscan.c
                    try_charge //memcontrol.c 路径见下面
                        high_work_func //memcontrol.c 作为 memcg->high_work 的回调
        ret_to_user //entry.S 【】返回用户空间
            work_pending //entry.S
                do_notify_resume
                    tracehook_notify_resume //tracehook.h
                        mem_cgroup_handle_over_high //memcontrol.c
                            reclaim_high //memcontrol.c
    alloc_slab_page //slub.c 【】slab分配页面路径
    kmem_getpages //slab.c
        charge_slab_page //slab.h
            memcg_charge_slab //slab.h
                memcg_kmem_charge_memcg //memcontrol.c
                    __memcg_kmem_charge //memcontrol.c
                        __memcg_kmem_charge_memcg //memcontrol.c
            memory_cgrp_subsys.can_attach //memcontrol.c 【】 cgroup内存接口
                mem_cgroup_can_attach //memcontrol.c
                    mem_cgroup_precharge_mc //memcontrol.c
            mem_cgroup_count_precharge //memcontrol.c 【】应该是内存占用统计相关逻辑
                charge_walk_ops.pmd_entry //memcontrol.c
                    mem_cgroup_move_charge_pte_range //memcontrol.c
                        mem_cgroup_do_precharge //memcontrol.c
                    collapse_huge_page //khugepaged.c
                    collapse_file //khugepaged.c
                    migrate_vma_insert_page //migrate.c
                    unuse_pte //swapfile.c
                    mcopy_atomic_pte //userfaultfd.c
                    __add_to_page_cache_locked //filemap.c
                    __replace_page //uprobes.c
                        mem_cgroup_try_charge
                    sk_forced_mem_schedule //tcp_output.c
                    inet_csk_accept //inet_connection_sock.c
                    __sk_mem_raise_allocated //sock.c
                        mem_cgroup_charge_skmem
                            try_charge //memcontrol.c
                    limit_in_bytes/soft_limit_in_bytes/kmem.limit_in_bytes/kmem.tcp.limit_in_bytes/memsw.limit_in_bytes 的write回调。//【】cgroup的文件节点
                        mem_cgroup_write //memcontrol.c
                            mem_cgroup_resize_max //memcontrol.c
                    force_empty 文件的write回调 //【】cgroup的文件节点
                        mem_cgroup_force_empty_write //memcontrol.c
                            mem_cgroup_force_empty //memcontrol.c
                        high 文件的write回调 //【】cgroup的文件节点
                            memory_high_write //memcontrol.c
                        max 文件的write回调 //【】cgroup的文件节点
                            memory_max_write //memcontrol.c
                                try_to_free_mem_cgroup_pages //vmscan.c
                            hibernate_preallocate_memory //power/snapshot.c 【】系统休眠前会执行一次
                                shrink_all_memory //vmscan.c
                                    do_try_to_free_pages //vmscan.c
                                        shrink_zones //vmscan.c
                        update_kswapd_threads_node //vmscan.c
                        multi_kswapd_run //vmscan.c
                        kswapd_run //vmscan.c
                            kthread_run(kswapd, pgdat, "kswapd%d:%d", nid, hid); 【】kswapd内核线程
                                kswapd //vmscan.c
                                    balance_pgdat //vmscan.c
                                        kswapd_shrink_node //vmscan.c
                                get_page_from_freelist //page_alloc.c【】buddy页面分配路径
                                    node_reclaim //vmscan.c
                                        __node_reclaim //vmscan.c
                                            shrink_node //vmscan.c
                                                shrink_slab //vmscan.c
                                                    list_for_each_entry(shrinker, &shrinker_list, list)
                                                        do_shrink_slab
                                                            shrinker->count_objects(shrinker, sc) //回调
                                                            shrinker->scan_objects(shrinker, shrinkctl) //回调
复制代码

注:charge是占用的意思。

 

posted on   Hello-World3  阅读(99)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2017-09-06 Linux设备树(4)—使用

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示