LinuxGod

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

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

2022年12月12日 248点热度

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大神网

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

最新 热点 随机
最新 热点 随机
ARM-Linux应用开发和单片机开发的不同ARM的应用 Linux下如何查看内核信息、发行版信息的信息? 《Linux内核编程》入门篇:降维为繁 Linux网卡驱动安装及配置指南 大专计算机有哪些课程,专业的1对1答疑! SamsungNote2Verizoni605onAndroid在Android系统上安装linux发行版 MPV的高级应用——Ubuntu最佳应用列表里的应用 手机上可以安装一套完整的Linux系统吗? Ubuntu上安装SMplayer.6.10-PPA源在CentOS5.5下安装使用 centos启动图形界面的方法.x1,关闭界面 Linux下进程与线程概念重构 Linux中的十大开源播放器C编写 多进程和多线程的区别,你知道几个? Linux发行版中可用的7款最佳开源视频播放器 Linux系统安装网卡驱动的具体操作流程进行说明 如何在Linux上安装视频播放器installvlc 晚上暴露于蓝光,睡眠质量大打折扣 如何安装便携式WiFi驱动程序?360wifi驱动的教程 CentOS云服务器搭建网站和CentOS搭建DNS解析服务 如何在linux上创建一个用户,减少不必要的沟通成本
嵌入式Linux操作系统学习规划+LINUX路线,主攻江苏电信天翼校园客户端故障指引及解决办法(101)英特尔GMAGMA950显卡驱动程序/WIN8/8.1电信校园网宽带用USB数据线共享给电脑无线上网国防科大开源操作系统:它只是一个吉祥的象征10个常用Linux文本查看命令及其详细说明和使用示例Linux嵌入式系统内核裁剪与定制方法的介绍情况淘宝教育热卖C语言编程开发C++程序设计零基础入门课程从CPU、内存、硬盘、显卡等这些方面安装Linux系统的最低配置Linux通过chkconfig设置开机启动服务创建的几种常见方式(技术分析)Linux多线程的使用与操作系统的区别通常rar命令由一个主命令加若干选项(可选)构成RedHatLinux中自动运行程序中的应用linux 读写文件 关于Linux内核的神秘面纱,你知道几个?使用wget实用程序的有用命令行工具的使用怎么设置linux开机项自启动?方式是怎样的?嵌入式Linux应用层与驱动层要想学习关于Linux内核的交叉编译步骤和方法:步骤、方法STM32嵌入式linux开发流程及应用程序分析-STMlinux下有哪些文件在介绍lsof命令实用用法介绍?
怎么设置linux开机项自启动?方式是怎样的? 环境变量配置文件输出已经是新路径 英伟达显卡驱动怎么安装?显卡怎么用? linux如何用u盘安装系统教程?(linux) Linux内核技术组成、组织和重要的数据结构等(组图) Linux嵌入式系统内核裁剪与定制方法的介绍情况 开源的linux运维监控工具对应的知识点运维工具有哪些 学习Linux系统的方法 Linux下中文乱码具体处理方法是什么?的人对电脑的操作 FIRO币怎么挖矿?币挖矿教程全解 Fedora17新特色特色说明桌面环境28bata集成了GNOME 如何实现本地机器与服务器之间的文件传输? 显卡性能测试软件(furmark),显卡06 设置需要执行的脚本新增调度任务可用两种方法介绍 test下的所有文件压缩成test.zip,并设置密码 如何在Linux系统中实现开机自启动呢? 统信UOS为啥火?国产操作系统又该如何发展?(组图) Linux系统下如何定位出CPU使用率过高的进程?(组图) Linux云主机无法SSH远程登录,上午还用得挺好 【Linux基础知识】Linux系统的启动流程经历(二)
标签聚合
linux服务器 命令 文件目录 linux系统 虚拟机 应用 操作 内核 文件 软件
书籍
课程
技术群
技术干货大合集↓
  • 2023年10月 / 8篇
  • 2023年9月 / 90篇
  • 2023年8月 / 93篇
  • 2023年7月 / 94篇
  • 2023年6月 / 90篇
  • 2023年5月 / 93篇
  • 2023年4月 / 90篇
  • 2023年3月 / 129篇
  • 2023年2月 / 84篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.