如何使用内核模块计算Linux中进程的匿名页面和共享页面

时间:2018-01-22 19:48:53

标签: c linux memory-management linux-kernel

我试图找到在Linux OS(ubuntu 14.04)上运行的c程序的驻留集大小。我得到正在运行的C程序的PID并将其传递给自定义内核模块。内核模块计算*task并提取*mm指针。然后我循环遍历所有VM areas,并在每个VM area中再循环遍历每个对齐virtual addresses的页面,并请求page_walk(virtual addresses)获取pte类型的结构pte_t。然后我使用pte_preset()函数检查RAM中是否存在实际的物理页面。

我面临的问题如下:

rss值与htoptop中显示的值不匹配。虽然我计算的值确实按比例增加,因为测试C程序访问更多内存(使用一些数组访问)。

我发现rss应用程序的htop值与Linux内核本身提供的get_mm_struct()函数调用给出的结果相同。

static inline unsigned long get_mm_rss(struct mm_struct *mm)
{
    return get_mm_counter(mm, MM_FILEPAGES) +
        get_mm_counter(mm, MM_ANONPAGES) +
        get_mm_counter(mm, MM_SHMEMPAGES);
}

我的查询是如何计算或检测这些匿名页面和共享页面?什么是需要检查的位?

谢谢!

1 个答案:

答案 0 :(得分:1)

执行此操作的正确方法是实现计数在数组中。尝试:

static inline unsigned long get_mm_rss(struct mm_struct *mm) 
{
    int k;
    unsigned long count = 0;
    for(k = 0; k < NR_MM_COUNTERS; k++) {
         long len = atomic_long_read(&mm->rss_stat.count[k]);
         if(len < 0)  
              len = 0;         
         count += len;
    }

}

行走物理页面

您需要使用 pte pmd (由内核中是否使用HUGETABLES驱动)的回调设置mm_walk结构来遍历物理页。

例如:

show_smap使用此:

    struct mm_walk smaps_walk = {
        .pmd_entry = smaps_pte_range,
#ifdef CONFIG_HUGETLB_PAGE
        .hugetlb_entry = smaps_hugetlb_range,
#endif
        .mm = vma->vm_mm,
    };
设置回叫后