2018年8月30日 星期四

解读dmesg中的内存初始化信息

http://linuxperf.com/?p=139


Linux kernel在引导过程中会在dmesg中报告如下的内存初始化信息,其实此时引导过程并未完成,initrd和init所占的内存尚未释放,最终kernel可用的内存比dmesg报告的available内存还会更多一点。
要理解以上信息的含义,还是看源代码吧,这条信息是在 mem_init() 函数中输出的:
以上代码中,free_all_bootmem()需要详细解释:在内核引导的初始阶段,buddy allocator和slab allocator等内存管理机制尚未就绪,所以使用的是bootmem allocator,到运行mem_init()的时候,bootmem的历史任务已经完成,所以调用free_all_bootmem()把它管理的内 存中未分配的部分全都释放掉。
absent_pages_in_range()用于统计物理内存中对kernel不可用的部分,因为有一些物理内存是被BIOS保留的,kernel用不了。
在全部物理内存中,除掉bootmem释放出来的空闲内存和kernel无法使用的absent内存,剩下的就是在kernel引导过程中已经分配掉的内存,称为reserved内存。Reserved内存主要包括initrd、初始化代码init、内核代码及数据(内核数据是动态变化的,这里所说的是引导阶段截至mem_init为止所产生的数据,包括存放页描述符struct page的mem_map[]数组等)。
注:initrd和初始化代码init在引导完成之后会被释放掉,所以最终的可用内存会比dmesg显示的available更多一点,相应的源代码可参见:
arch/x86/mm/init.c: free_initrd_mem() 和 free_initmem()。
在dmesg中可以看到释放时输出的日志,注意看init的大小:
正因如此,最终用”free”命令看到的total memory比dmesg里看到的available memory更多,以本系统为例,”free”命令看到的total 3809036k,比dmesg看到的available memory 3789320k更多,(3809036k – 3789320k) = (24k + 18088k + 1604k):
注:关于reserved memory的更多详情可参见链接中的表1:
http://www.tldp.org/LDP/khg/HyperNews/get/memory/linuxmm.html
所以内存初始化信息的解读如下:
  • 3789320k/4915200k available
    分母4915200k表示物理内存的大小,
    分子3789320k表示可供kernel分配的 free memory的大小;
  • 795332k absent
    表示不可用的物理内存大小。譬如有一些物理内存被BIOS保留、对kernel是不可用的,这部分物理内存被计入”absent”之中。
  • 330548k reserved
    包括【initrd】和【内核代码及数据】等,详见上面的解释。其中内核代码和部分数据包含在下列统计值中:
    • 6243k kernel code :
      表示kernel的代码,属于reserved memory;
    • 4180k data :
      表示kernel的数据,属于reserved memory;
    • 1604k init :
      表示init code和init data,属于reserved memory,但引导完成之后会释放给free memory。
它们之间的关系如下:
  • available = 物理内存 – absent – reserved
  • reserved 包括 kernel code, data 和 init,由于它还包括initrd和其它更多的内容,所以reserved远远大于 kernel code + data + init 之和。
参考资料:
http://winfred-lu.blogspot.com/2011/03/linux-boot-memory-allocator-mips.html

沒有留言: