smap节点,位于/proc/{pid}/smaps。

通过这个节点可以看到一个进程映射的内存信息,不会包括设备使用的内存,比如gpumem。

smaps节点内核定义

kernel/msm-4.19/fs/proc/base.c#ifdef CONFIG_PROC_PAGE_MONITORREG("clear_refs", S_IWUSR, proc_clear_refs_operations),REG("smaps",     S_IRUGO, proc_pid_smaps_operations),REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),REG("pagemap",    S_IRUSR, proc_pagemap_operations),
#endif
​
​
kernel/msm-4.19/fs/proc/task_mmu.cconst struct file_operations proc_pid_smaps_operations = {.open       = pid_smaps_open,.read       = seq_read,.llseek     = seq_lseek,.release    = proc_map_release,
};

open系统调用分析

对smaps节点的open系统调用,我觉得应该类似binder_open,打开这个节点做一些初始化工作

调用堆栈如下:

kernel/msm-4.19/fs/proc/task_mmu.c    pid_smaps_open()--->kernel/msm-4.19/fs/proc/task_mmu.c    do_maps_open()--->kernel/msm-4.19/fs/proc/task_mmu.c    proc_maps_open()

重点看一下阿proc_maps_open函数调用了__seq_open_private方法,这一番操作实际上是把smaps文件与proc_pid_smaps_op关联上。

实际上就是在seq_file结构体的seq_operations指针上放了proc_pid_smaps_op,之后对smaps进行cat操作就会执行到show_smap()方法。

具体的细节可以按照

kernel/msm-4.19/fs/proc/task_mmu.c    static int proc_maps_open(struct inode *inode, struct file *file,const struct seq_operations *ops, int psize)
{//在这里初始化,关联了seq_file的proc_pid_smaps_opstruct proc_maps_private *priv = __seq_open_private(file, ops, psize);
​priv->inode = inode;priv->mm = proc_mem_open(inode, PTRACE_MODE_READ);if (IS_ERR(priv->mm)) {int err = PTR_ERR(priv->mm);
​seq_release_private(inode, file);return err;}
​return 0;
}
​
kernel/msm-4.19/include/linux/seq_file.hstruct seq_file {char *buf;size_t size;size_t from;size_t count;size_t pad_until;loff_t index;loff_t read_pos;u64 version;struct mutex lock;const struct seq_operations *op;int poll_event;const struct file *file;void *private;
};
​

show方法分析

在执行cat /proc/{pid}/smaps之后,会执行下面的调用栈。

在调用栈(2)的smap_gather_stats()函数中,会初始化一个mm_walk结构体,并设置smaps_pte_range()函数作为回调,

所以在smap_gather_stats()函数最后执行walk_page_vma()后,遍历页表时会回调smaps_pte_range()函数。

然后在smaps_account方法中把VMA的所有子项与结构体mem_size_stats关联起来。

最后在show_smap方法里就可以通过打印mem_size_stats中的数据,将一个进程的一块VMA信息打印出来了。

分析到这里,可以知道smaps节点的信息都是从mm_struct中的vma中获得的。

调用栈:

1. kernel/msm-4.19/fs/proc/task_mmu.c    show_smap()
2.     --->kernel/msm-4.19/fs/proc/task_mmu.c    smap_gather_stats()
3.       --->kernel/msm-4.19/mm/pagewalk.c    walk_page_vma()
4.          --->kernel/msm-4.19/mm/pagewalk.c    __walk_page_range()
5.              --->kernel/msm-4.19/mm/pagewalk.c    walk_pgd_range()
6.                  --->kernel/msm-4.19/mm/pagewalk.c    walk_p4d_range()
7.                      --->kernel/msm-4.19/mm/pagewalk.c    walk_pud_range()
8.                          --->kernel/msm-4.19/mm/pagewalk.c    walk_pmd_range()
9.                              --->kernel/msm-4.19/fs/proc/task_mmu.c    smaps_pte_range()
10.                                 --->kernel/msm-4.19/fs/proc/task_mmu.c    smaps_pte_entry()
11.                                     --->kernel/msm-4.19/fs/proc/task_mmu.c    smaps_account()

每执行一次,会打印smaps节点的一块VMA信息,如下:

kernel/msm-4.19/fs/proc/task_mmu.cstatic const struct seq_operations proc_pid_smaps_op = {.start  = m_start,.next   = m_next,.stop   = m_stop,.show   = show_smap
};
​
​
static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,struct mm_walk *walk)
{struct vm_area_struct *vma = walk->vma;pte_t *pte;spinlock_t *ptl;
​ptl = pmd_trans_huge_lock(pmd, vma);.../** The mmap_sem held all the way back in m_start() is what* keeps khugepaged out of here and from collapsing things* in here.*/pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);for (; addr != end; pte++, addr += PAGE_SIZE)//在这里遍历此vma的每一个页表项smaps_pte_entry(pte, addr, walk);pte_unmap_unlock(pte - 1, ptl);
​return 0;
}
​
​

\

【安卓源码】简单分析smaps节点相关推荐

  1. poco源码简单分析

    自动化工具poco源码简单分析 Airtest简介 Airtest是网易游戏开源的一款UI自动化测试项目,目前处于公开测试阶段,该项目分为AirtestIDE.Airtest.Poco.Testlab ...

  2. Hessian 源码简单分析

    Hessian 源码简单分析 Hessian 是一个rpc框架, 我们需要先写一个服务端, 然后在客户端远程的调用它即可. 服务端: 服务端通常和spring 做集成. 首先写一个接口: public ...

  3. FFmpeg的HEVC解码器源码简单分析:概述

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  4. FFmpeg的HEVC解码器源码简单分析:解码器主干部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  5. JSP 编译和运行过程与JSP源码简单分析

    JSP 编译和运行过程与JSP转移源码简单分析 Web容器处理JSP文件请求的执行过程主要包括以下4个部分: 1. 客户端发出Request请求 2. JSP Container 将JSP转译成Ser ...

  6. 线程的3种实现方式并深入源码简单分析实现原理

    前言 本文介绍下线程的3种实现方式并深入源码简单的阐述下原理 三种实现方式 Thread Runnable Callable&Future 深入源码简单刨析 Thread Thread类实现了 ...

  7. reentrantlock失效了?_ReentrantLock 源码简单分析

    JAVA中锁的实现最常见的方式有两种,一种是 synchronized关键字,一种是Lock.实际的开发过程中,要对这两种方式进行取舍. synchronized是基于JVM层面实现的, Lock却是 ...

  8. Linux·内核源码简单分析

    目录 系统总体流程: 各个目录的阅读总结: (一) boot (二)内核初始化init (三)kernel: (四)mm内存管理 (五)文件系统模块fs: 系统总体流程: 系统从boot开始动作,把内 ...

  9. ChaLearn Gesture Challenge_3:Approximated gradients源码简单分析

    前言 上一篇博文ChaLearn Gesture Challenge_2:examples体验 中简单介绍了CGC官网提供的丰富的sample,本节来简单分下其中的一个sample源码,该sample ...

  10. Enemy源码简单分析

    这是这个项目的网页链接,以下是关于enemy源代码的粗略分析. https://github.com/freakanonymous/enemy 弗兰克,是一个全职的恶意代码工程师,会不定期更新enem ...

最新文章

  1. C#使用ping命令
  2. 第九十二期:多少程序员注意到了「中台」的背面?
  3. 在上级对自己做绩效评估之前
  4. 关于常用的git命令列表
  5. 区块链教程Fabric1.0源代码分析flogging(Fabric日志系统)
  6. Python 语言简介与入门(1)
  7. 基于NXP iMX8测试Secure Boot功能部署
  8. c语言国二题库选择填空题,国二c语言笔试题库(含答案),选择填空.doc
  9. java版b2b2c社交电商spring cloud分布式微服务 (三) 服务消费者(Feign)
  10. Python API+Postman+jmeter
  11. CF 1696 E. Placing Jinas 组合数 2000
  12. 梆梆加固的病毒分析-破解篇
  13. 成为黑客需要学习什么技能?
  14. Mac下Smb的使用
  15. 新版标准日本语初级_第三十课
  16. Android:国家气象局提供的天气预报接口(完整Json接口)
  17. 【 CF1186D,E,F】Vus the Cossack and Numbers/Vus the Cossack and a Field/Vus the Cossack and a Graph
  18. 华科提出首个用于伪装实例分割的一阶段框架OSFormer
  19. Ansible Role详解
  20. 重庆北大青鸟python培训

热门文章

  1. 微信小程序分享小程序码的生成,多参数以及参数的获取
  2. 计算机显示器分辨率,电脑显示器分辨率调多少合适
  3. 目标检测标签分配之 OTA 和 SimOTA 细节学习
  4. 【百战GAN】StyleGAN原理详解与人脸图像生成代码实战
  5. BIMC电子商务外包服务独特之处
  6. Fedora 9在用VMware 5.5、6.5虚拟机安装和硬盘安装中遇见的几点问题
  7. 基于ASP.NET开发的固定资产管理系统源码 企业固定资产管理系统源码
  8. flutter上分之路1-新手教学(配置安装)
  9. 查看oracle的SID
  10. java开发购物系统菜单_Java控制台购物系统