内存管理-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 2024-09-06 21:34  Hello-World3  阅读(52)  评论(0编辑  收藏  举报

导航