linux内核源码解析:linux源码下载及top命令中的RES是如何计算的

CLion:2019.3.6
源码操作平台:Macbook Pro 10.12.6
源码项目:linux源码

一、背景

通过上一节,我们知道了top中的RES是从/proc/pid/statm文件中读取出来的,详细的可以看这篇博客《linux的top命令源码解析:RES指标》,这次我们要弄清楚/proc/pid/statm文件中resident值是怎么计算出来的。

二、克隆linux源码

2.1 linux源码

github上,linux的源码地址是:https://github.com/torvalds/linux
linux源码有2.42G多,直接在github上克隆的话,速度才20-400kbits,速度相当的慢,所以可以从国内的码云上进行clone,速度能达到10Mbits,
码云上有linux的mirrors,地址是:https://gitee.com/mirrors/linux?_from=gitee_search
由于linux的太大,如果直接执行clone的话会导致失败,如下所示:

Cloning into 'linux'...
remote: Counting objects: 20248, done.
remote: Compressing objects: 100% (10204/10204), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining 
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

在stackoverflow上找到一个解决办法:error: RPC failed; curl transfer closed with outstanding read data remaining
首先执行git clone git@gitee.com:mirrors/linux.git --depth 1进行浅度clone:

192:gitee bingsanlang$ git clone git@gitee.com:mirrors/linux.git --depth 1
Cloning into 'linux'...
remote: Enumerating objects: 74374, done.
remote: Counting objects: 100% (74374/74374), done.
remote: Compressing objects: 100% (69764/69764), done.
remote: Total 74374 (delta 6338), reused 21640 (delta 3816), pack-reused 0
Receiving objects: 100% (74374/74374), 195.69 MiB | 5.79 MiB/s, done.
Resolving deltas: 100% (6338/6338), done.
Updating files: 100% (70001/70001), done.
warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:
  'include/uapi/linux/netfilter/xt_CONNMARK.h'
  .....省略.......
  'tools/memory-model/litmus-tests/Z6.0+pooncelock+pooncelock+pombonce.litmus'

进入linux目录,执行fetch 将剩余代码clone下来:

192:gitee bingsanlang$ cd linux/
192:linux bingsanlang$ git fetch --unshallow
remote: Enumerating objects: 7588438, done.
remote: Counting objects: 100% (7588435/7588435), done.
remote: Compressing objects: 100% (1215473/1215473), done.
remote: Total 7530352 (delta 6369843), reused 7426929 (delta 6266881), pack-reused 0
Receiving objects: 100% (7530352/7530352), 2.42 GiB | 9.78 MiB/s, done.
Resolving deltas: 100% (6369843/6369843), completed with 51779 local objects.
remote: Enumerating objects: 659, done.
remote: Counting objects: 100% (659/659), done.
remote: Compressing objects: 100% (659/659), done.
remote: Total 659 (delta 0), reused 659 (delta 0), pack-reused 0
Receiving objects: 100% (659/659), 280.11 KiB | 612.00 KiB/s, done.
From gitee.com:mirrors/linux
 * [new tag]                   v2.6.12     -> v2.6.12
 .....省略.......
 * [new tag]                   v5.9-rc1    -> v5.9-rc1

下载完成后,当前目录下主要有如下源码文件:

192:linux bingsanlang$ ls
COPYING		Kconfig		README		crypto		init		mm		security	virt
CREDITS		LICENSES	arch		drivers		ipc		net		sound
Documentation	MAINTAINERS	block		fs		kernel		samples		tools
Kbuild		Makefile	certs		include		lib		scripts		usr

2.2 linux源码导入到Clion

参考《Clion 导入Makefile格式的C语言源程序:procps项目》将linux源码导入到CLion中,导入后如下结构:在这里插入图片描述

2.3 /proc/pid/statm的resident数据源码分析

/proc/pid/statm 中的数据,是经过内核函数 task_statm 读取而后由 procfs 写入的。
具体源码如下:
文件:linux/fs/proc/task_mmu.c
其中的片段如下:

unsigned long task_statm(struct mm_struct *mm,
			 unsigned long *shared, unsigned long *text,
			 unsigned long *data, unsigned long *resident)
{
   
	*shared = get_mm_counter(mm, MM_FILEPAGES) +
			get_mm_counter(mm, MM_SHMEMPAGES);
	*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
								>> PAGE_SHIFT;
	*data = mm->data_vm + mm->stack_vm;
	*resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
	return mm->total_vm;
}

从代码中可以看到,resident的大小 = 共享内存+MM_ANONPAGES大小,关于MM_ANONPAGES后面后讲述,简单介绍下get_mm_count函数:
文件:《

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值