LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

Linux内核虚拟内存管理的难点分析与解决办法(一)

2022年12月12日 135点热度

Cheetah,曾为U-boot社区和Linux内核社区提交过若干补丁,主要从事Linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,喜欢阅读内核源代码,在不断的学习和工作中深入理解内存管理,进程调度,文件系统,设备驱动等内核子系统。

嵌入式进阶教程分门别类整理好了,看的时候十分方便,由于内容较多,这里就截取一部分图吧。

深入理解java虚拟 下载_深入理解linux虚拟内存管理_深入理解linux网络技术内幕

需要的朋友私信【内核】即可领取。

为了系统的安全性,Linux内核将各个用户进程运行在各自独立的虚拟地址空间,用户进程之间通过虚拟地址空间相互隔离,不能相互访问,一个进程的奔溃不会影响到整个系统的异常也不会干扰到系统以及其他进程运行。

Linux内核可以通过共享内存的方式为系统节省大量内存,例如fork子进程的时候,父子进程通过只读的方式共享所有的私有页面。再比如通过IPC共享内存方式,各个不相干的进程直接可以共享一块物理内存等等。

我们都知道操作系统开启mmu之后cpu访问到的都是虚拟地址,当cpu访问一个虚拟地址的时候需要通过mmu将虚拟地址转化为物理地址,这叫做正向映射。而与本文相关的是反向映射,它主要是通过物理页来找到共享这个页的所有的vma对应的页表项,这是本文讨论的问题。

注:反向映射机制是Linux内核虚拟内存管理的难点也是理解内存管理的关键技术之一!!

反向映射的发展

实际上在早期的Linux内核版本中是没有反向映射的这个概念的,那个时候为了找到一个物理页面对应的页表项就需要遍历系统中所有的mm组成的链表,然后对于每一个mm再遍历每一个vma,然后查看这个vma是否映射了这页,这个过程极其漫长而低效,有的时候不得不遍历完所有的mm然后才能找映射到这个页的所有pte。

后来人们发现了这个问题,就在描述物理页面的page结构体中增加一个指针的方式来解决linux主机,通过这个指针来找到一个描述映射这个页的所有pte的数组结构,这对于反向映射查找所有pte易如反掌,但是带来的是浪费内存的问题。

接着就在2.6内核的时候,内核大神们想到了复用page结构中的mapping字段,然后通过红黑树的方式来组织所有映射这个页的vma,形成了匿名页和文件页的反向映射机制。

但是后来匿名页的反向映射遇到了效率和锁竞争激烈问题,就促使了目前使用的通过avc的方式联系各层级反向映射结构然后将锁的粒度降低的这种方式。可以看到反向映射的发展是伴随着Linux内核的发展而发展,是一个不断进行优化演进的过程。

反向映射应用场景

深入理解linux网络技术内幕_深入理解linux虚拟内存管理_深入理解java虚拟 下载

那么为何在Linux内核中需要反向映射这种机制呢?它究竟为了解决什么样的问题而产生的呢?

试想有如下场景:

(1)一个物理页面被多个进程的vma所映射,系统过程中发生了内存不足,需要回收一些页面,正好发现这个页面是适合我们回收利用的,我们能够直接把这个页面还给伙伴系统吗?答案肯定是不能。因为这个页面被很多个进程所共享,我们必须做的事情就是断开这个页面的所以映射关系,这就是反向映射所做的事情。

(2)一些情况我们需要将一个页面迁移到另一个页面,但是牵一发而动全身,可能有一些进程已经映射这个即将要迁移的页面到自己的vma中,那么这个时候同样需要我们知道究竟这个页面被哪些vma所映射呢?这同样是反向映射所做的事情。

实际上,反向映射的主要应用场景为内存回收和页面迁移,当系统发生内存回收和页面迁移的时候,对于每一个候选页Linux内核都会判断是否为映射页,如果是,就会调用try_to_unmap 来解除页表映射关系深入理解linux虚拟内存管理,本文也主要来从try_to_unmap函数来解读反向映射机制。

如果我们在细致到其他的内核子系统会发现,在内存回收,内存碎片整理,CMA, 巨型页,页迁移等各个场景中都能发现反向映射所做的关键性的工作,所有理解反向映射机制在Linux内核中的实现是理解掌握这些子系统的基础和关键性所在,否则你即将不能理解这些技术背后的脊髓所在,所以说理解反向映射这种机制对于理解Linux内核内存管理是至关重要的!!!

匿名页的反向映射

匿名页的共享主要发生在父进程fork子进程的时候红旗linux安装,父fork子进程时,会复制所有vma给子进程,并通过调用dup_mmap->anon_vma_fork建立子进程的rmap以及和长辈进程rmap关系结构:

主要通过anon_vma这个数据结构体中的红黑树将共享父进程的页的所有子进程的vma联系起来(通过anon_vma_chain 来联系对应的vma和av),当然这个关系建立比较复杂,涉及到vma,avc和av这些数据结构体。.

而在缺页异常do_anonymous_page的时候将page和vma相关联。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_anon ->anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root,pgoff_start, pgoff_end) ->rwc->rmap_one ->try_to_unmap_one

对于候选页,会拿到候选页相关联的anon_vma,然后从anon_vma的红黑树中遍历到所有共享这个页的vma,然后对于每一个vma通过try_to_unmap_one来处理相对应的页表项,将映射关系解除。

文件页的反向映射

文件页的共享主要发生在多个进程共享libc库,同一个库文件可以只需要读取到page cache一次,然后通过各个进程的页表映射到各个进程的vma中。

管理共享文件页的所以vma是通过address_space的区间树来管理,在mmap或者fork的时候将vma加入到这颗区间树中:

发生文件映射缺页异常的时候,将page和address_space相关联。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_file ->vma_interval_tree_foreach(vma, &mapping>i_mmap,pgoff_start, pgoff_end) ->rwc->rmap_one

对于每一个候选的文件页,如果是映射页,就会遍历page所对应的address_space的区间树,对于每一个满足条件的vma,调用try_to_unmap_one来找到pte并解除映射关系。

ksm页的反向映射

深入理解java虚拟 下载_深入理解linux虚拟内存管理_深入理解linux网络技术内幕

ksm机制是内核将页面内容完全相同的页面进行合并(ksm管理的都是匿名页),将映射到这个页面的页表项标记为只读,然后释放掉原来的页表,来达到节省大量内存的目的,这对于host中开多个虚拟机的应用场景非常有用。

ksm机制中会管理两棵红黑树,一棵是stable tree,一棵是unstable tree,stable tree中的每个节点stable_node中管理的页面都是页面内容完全相同的页面(被叫做kpage),共享kpage的页面的页表项都会标记为只读,而且对于原来的候选页都会有rmap_item来描述他的反向映射(其中的anon_vma成员的红黑树是描述映射这个候选页的所有vma的集合)深入理解linux虚拟内存管理,合并的时候会加入到对应的stable tree节点和链表中。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_ksm //mm/ksm.c -> hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) ->anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,0, ULONG_MAX) ->rwc->rmap_one

对于一个ksm页面,反向映射的时候,会拿到ksm页面对应的节点,然后遍历节点的hlist链表,拿到每一个anon_vma,然后就和上面介绍的匿名页的反向映射一样了,从anon_vma的红黑树中找到所有的vma,最后try_to_unmap_one来找到pte并解除映射关系。

总结

前面我们介绍了反向映射的三种类型,匿名页,文件页和ksm页的反向映射,分别通过page所对应的的vma, address_space, stable_node结构来查找vma。当然我们只是介绍了Linux内核中的反向映射的冰山一角,主要是try_to_unmap函数,其实每种反向映射各个数据结构建立的过程错综复杂,一篇文章三言两语也说不清楚,他们散落在Linux内核源代码的进程创建fork,内存映射mmap,缺页异常处理,文件系统等各个角落。

诚然,如果我们搞不清楚各种反正映射所对应的各种数据结构之间的关系,或者只是有一些概念上的了解,并没有真正掌握这种机制的实现原理,对于我们来理解Linux内核虚拟内存管理来说是一种障碍,不懂得反向映射内存管理 中的很多问题是搞不明白的!

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 内存映射 内存碎片 内存管理 虚拟内存 页表
最后更新:2022年12月12日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
查看系统版本 linux “”的有关知识,不少人都会遇到这样的困境 Linux在内核中是如何记录进程资源的?你能从C语言源代码层面分析下吗? 【】原操作系统配备内核源代码,更不能进行内核模块实验 【Linux基础知识】与文件权限管理的Linux关系 linux/管理员管理员发布于5年前34(图) Linux和Unix操作系统之间有区别但也有联系?(一) Ubuntu系统如何升级和更新Linux内核版本?将推荐 Linux内核技术组成、组织和重要的数据结构等(组图) 【报错日志】一下升级linux内核的启动顺序为0 Linux终端窗口中输入mysql-V以显示MySQL版本信息sky 计算机操作系统全新版装系统盘点、理念与系统的优缺点 linux中常用的用户管理命令:1groups?列出当前用户所属 Linux下如何设置开机启动启动脚本?学算法 Linux中已经安装好了mysql命令 Linux系统用户系统上的三种类型的帐户的介绍 Linux下的开机启动设置方法是什么?脚本或服务 谷歌更新Linux内核构建的公共内核库:添加对kokoro作业的支持 linux下mysql中可以使用REVOKE语句来删除某个用户的权限 内核的角度来看,调用hotplug和通常的hotplug环境 Linux系统在开机的时候自动加载某些脚本或系统服务
Linux5.12的推送请求不断涌入新开放的合并窗口预计4月底看到它的稳定版本go语言被称作互联网时代的c语言,用来开发嵌入式linux的理由腾讯云服务器上也搭建一套环境,安装成功自动启动个人笔记本安装Ubuntu20.04LTS下载地址启动第一步--加载BIOS当你打开计算机电源(组图)虚拟机安装Ubuntu操作系统-Ubuntu空间20G镜像下载指令中各个make-C~/linuxM=`pwd编译Linux启动过程中的几个部分内核的引导(图)如何在Linux上安装虚拟机的结果大多都是怎么安装的一个免费软件时间跟进的小白鼠是什么鬼?专题计算机是如何启动的?、内核操作系统的启动流程学习Linux最简单、最实用的环境就是虚拟机环境(上)基于命令修改文件的权限命令-ld1.Linux磁盘分区和目录Linux发行版本之间的差别很少?国内性价比很高的Linux虚拟主机系统安装的流程是什么?Linux下修改文件权限的权限与所有权的实现就显得很有必要linux到底难不难学呢?推荐可以查看Linux命令大全Linux中修改文件权限的命令、创建者所在组、所有人Linux的内核放在了哪里?/boot的启动目录一览阿里云>社区>主题地图S>查看存储推荐
关于IA-32/Linux进程内核空间的叙述中,错误的是 如何在Linux系统上下载和安装Steam呢?如何操作 UNIX网络编程卷1:套接字联网API第3版pdf百度网盘下载地址 Linux强烈建议采用自定义的系统服务实现开机启动程序的脚本方法 Linux七种运行级别(0-6)预置的启动流程 Linux查看系统和内核版本在不同系统的一些命令表现 中科红旗(北京)信息科技有限公司研发的Linux桌面操作系统社区预览版 服务器上安装linux系统的具体操作过程-如何选择系统? linux中命令介绍Cat命令(concatenate命令)介绍命令 linux虚拟机软件 Linux在安装的时候要注意什么?Linux安装注意事项 Linux中国荣誉研究生申请之cron定时器 Linux下的文件一旦被删除,是难以恢复的? go语言被称作互联网时代的c语言,用来开发嵌入式linux的理由 1.useradd命令可以创建一个新的用户帐号其最基本用法 Linux基金会主席Zemlin宣布中标软件和阿里云成为Linux会员 想要在安卓手机上体验Linux操作系统在直接途径上并不可能 VMwareUbuntuserver系统安装教程系统镜像下载地址—> Windows下默认的编码是GBK-8,怎么办? 在单片机与嵌入式linux的应用与驱动操作(组图) SteelEyeLifeKeeper集群软件关键特性企业数据中心
标签聚合
电脑 unix linux系统 linux服务器 sudo 虚拟机 shell 文件目录 软件 命令模式
书籍
课程
技术群
技术干货大合集↓
  • 2023年2月 / 26篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.