0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ARM64 Linux内核页表的块映射

Linux阅码场 来源:Linuxer 作者:Linuxer 2021-01-04 13:37 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

内核文档Documentation/arm64/memory.rst描述了ARM64 Linux内核空间的内存映射情况,应该是此方面最权威文档。

以典型的4K页和48位虚拟地址为例,整个内核空间的虚拟地址分布如下:

173d710c-4e4d-11eb-8b86-12bb97331649.png

从ffff000000000000到ffff7fffffffffff是一段针对物理地址的线性映射区,最大支持128TB的物理地址空间,这一段地址非常类似ARM32的low memory映射区。

我们看看这种情况下的页表,我们既可以用最终的【20:12】对应的PTE映射项,以4K为单位,进行虚拟地址到物理地址的映射;又可以以【29:21】对应的PMD映射项,以2M为单位,进行虚拟地址到物理地址的映射。

1764476e-4e4d-11eb-8b86-12bb97331649.png

对于用户空间的虚拟地址而言,当我们进行的是PMD映射的时候,我们得到的是Huge Page,ARM64的2MB的huge page,在虚拟和物理上都连续,它在实践工程中的好处是,可以减小TLB miss,因为,如果进行了2MB的映射,整个2MB不再需要PTE,映射关系大为减小。

178dd1ce-4e4d-11eb-8b86-12bb97331649.png

对于内核空间而言,从ffff000000000000到ffff7fffffffffff的这段虚拟地址,如果与物理地址进行的是一种PMD映射的话,显然也可以达到同样的效果。但是,这不意味着它们就是Huge Page。众所周知,内核开机把物理地址往虚拟地址进行线性映射,并不意味着这片内存被内核拿走了,它只是进行了一种映射,以便日后调用kmalloc(),get_free_pages()等API申请的内存是直接已经有虚实映射的。所以,即便内核进行的就是PMD映射,在内存的分割上,还是可以以4K为单位的:

17c8ca68-4e4d-11eb-8b86-12bb97331649.png

所以,即便我们在内核空间进行PMD映射,里面的每个蓝色圆圈(一个4K页),还是可以被单独分配的,这种分配可以是kmalloc、vmalloc,用户态的malloc等。内核态进行的PMD映射,不意味着相关的2MB成为了huge page,它纯粹只是为了服务于当内核以线性映射的虚拟地址访问该物理地址的时候(我们认为内核大多数时候是用这个线性映射的虚拟地址的),减小TLB miss。

当然,更牛逼的情况下,内核应该也可以直接用【38:30】位的PUD来进行映射,这样映射关系是1GB的,则整个1GB后面占TLB的时候,只需要占一个入口。

1835a250-4e4d-11eb-8b86-12bb97331649.png

当然,如果用户态的虚实映射是这样的,用户实际得到了一个1GB的巨页。但是对于内核的线性映射区域而言,即便我们进行了1GB的PUD映射,这1G内部就可以进一步切割为4KB页或者2MB的巨页。记住:内核态的线性映射区的映射只是个映射关系,不是个分配关系。比如下面的1GB的内核线性映射的1GB区域,仍然可以被4K分配走,或者被用户以huge page以2MB为单位分配走:

185868b2-4e4d-11eb-8b86-12bb97331649.png

我们需要一个真实的调试手段来验证我们的想法,这个调试手段就是PTDUMP(Page Table Dump),相关的代码在ARM64内核的:

arch/arm64/mm/ptdump.c和ptdump_debugfs.c

我们把它们全部选中,这样我们可以得到一个debugfs接口

/sys/kernel/debug/kernel_page_tables

来获知内核态页表的情况。

我用qemu启动了一个4GB内存的ARM64虚拟机,可以看到前1GB的虚拟地址空间大多数是PMD和PTE映射,后面的3GB,全是PUD映射:

188ac456-4e4d-11eb-8b86-12bb97331649.png

我的内核启动参数加了rodata=0:

$ cat/proc/cmdlineroot=/dev/vda2 rw console=ttyAMA0 ip=dhcp rodata=0

原因是内核在几种情况下,是不会做这种PMD和PUD映射的,相关代码见于:

18d0ee68-4e4d-11eb-8b86-12bb97331649.png

191e8b00-4e4d-11eb-8b86-12bb97331649.png

rodata_full在默认情况下总是成立的,它对应着内核的一个Config选项CONFIG_RODATA_FULL_DEFAULT_ENABLED, "Apply r/o permissions of VM areas also to their linear aliases",这个选项提高了内核的安全性,但是减小了内核的性能。

197a2640-4e4d-11eb-8b86-12bb97331649.png

我在内核启动参数加的rodata=0实际上是让rodata_full为false。如果我把这个kernel启动选项去掉,我得到的内核页表是完全不一样,线性映射区也全部是PTE映射:

199d2ee2-4e4d-11eb-8b86-12bb97331649.png

最后,值得一提的是,不仅线性映射区可以使用PMD映射,vmemmap映射区也是在4K页面情况下,默认用PMD映射的:

1a0676fe-4e4d-11eb-8b86-12bb97331649.png

字节跳动的宋牧春童鞋发了一个patchset,企图在用户分得巨页的情况下,删除巨页内部的4KB的小page占用的page struct的内存消耗,这个patchset在圣诞节前目前发到了V11:

https://lore.kernel.org/linux-mm/20201222142440.28930-1-songmuchun@bytedance.com/

1a6a8f18-4e4d-11eb-8b86-12bb97331649.png

在这个patchset中,它就需要拆分vmemmap的PMD映射为PTE映射:

1b367c4a-4e4d-11eb-8b86-12bb97331649.png

这个patchset的原理建立在,当内核以4KB分页的时候,每个page需要64字节的page struct。但是,当用户把它分配为巨页的时候,时候,我们不再需要一个个4KB单独用page struct描述,对于这种compound page的情况,我们应该可以把后面的page struct的内存直接释放掉,因为情况完全是雷同的,这样可以剩下不少内存。

责任编辑:xj

原文标题:宋宝华: ARM64 Linux内核页表的块映射

文章出处:【微信公众号:Linuxer】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    135

    文章

    9499

    浏览量

    388674
  • 内核
    +关注

    关注

    4

    文章

    1436

    浏览量

    42489
  • Linux
    +关注

    关注

    88

    文章

    11628

    浏览量

    217956
  • 板块
    +关注

    关注

    0

    文章

    4

    浏览量

    7672

原文标题:宋宝华: ARM64 Linux内核页表的块映射

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux内核模块的加载机制

    \"GPL\") bool sig_ok;// 签名验证结果 };然后进行内存分配 1、使用vmalloc()在内核空间分配内存,映射模块的代码和数据段。 2、标记可执行(需
    发表于 11-25 06:59

    【OK3506-S12Mini试用评测】编译你的第一个内核模块

    -x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/ 工具链前缀 : arm-none-linux-gnueabihf- 2
    发表于 10-24 21:00

    【米尔NXP i.MX 91开发板评测】移植和运行RT-Linux,实时性能测试

    CONFIG_PREEMPT_RT make olddefconfig echo \"编译内核和模块...\" make -j$(nproc) ARCH=arm64
    发表于 09-01 10:11

    【HZ-RK3568开发板免费体验】HZ-RK3568开发板操作系统编译

    RK_KERNEL_CFG=rockchip_linux_defconfig RK_KERNEL_DTB=kernel/arch/arm64/boot/dts/rockchip
    发表于 08-17 09:15

    请问各位dayu200是不是不支持烧录64位的OpenHarmony

    我自己编译了OpenHarmony5.0.2的镜像,发现如果使用arm64参数编译为64位版本,烧录后卡在开机动画无法开机,如果编译为32位就可以正常。请问dayu200不支持64位系统吗?
    发表于 08-16 17:39

    【HZ-RK3568开发板免费体验】3、开启Linux Kernel RT功能

    /aarch64-none-linux-gnu- make ARCH=arm64 rockchip_linux_defconfig rockchip_rt.config make -C /path/to/SDK/kernel
    发表于 07-22 14:03

    Windows Arm64托管运行器正式支持GitHub Actions

    过去一年,Arm 与 GitHub 持续紧密合作,致力于为基于 Arm 平台的开发者打造更便捷、更高效的开发体验。GitHub 推出的 Arm 托管运行器正在革新应用程序的开发与部署流程,而近期推出
    的头像 发表于 04-28 14:23 900次阅读

    迅为RK3568开发板内核模块实现-编写 Makefile

    如下(图 4-5)所示: 代码解释如下: 第 1 行设置 ARCH 变量为 arm64 第 2 行设置交叉编译器前缀为 aarch64-linux-gnu- 第 3 行 obj-m += &
    发表于 04-24 13:36

    如何在Linux内核5.18版本之后和64位架构中从内核空间调用ioctl?

    我尝试在最近的内核中重新构建以前版本 (4.19) 的 Linux 设备驱动程序,即嵌入式平台上的 6.1.22,ARM64 架构。 驱动程序管理 tty 设备。 当我调用类似于用户空间
    发表于 04-02 06:06

    如何使用CAAM实现设备映射器?

    您好,我正在尝试使用 CAAM 实现设备映射器。 在配置了内核并添加了所有必需的配置选项(AN12714附录 A)并使用所需的工具 (CORE_IMAGE_EXTRA_INSTALL
    发表于 03-27 06:45

    树莓派4 性能大比拼:标准Linux与实时Linux 4.19内核的延迟测试

    引言本文是对我之前关于RaspberryPi3同一主题的帖子的更新。与之前的帖子一样,我使用的是随Raspbian镜像提供的标准内核,以及应用了RT补丁的相似内核版本。对于实时版,我
    的头像 发表于 03-25 09:39 656次阅读
    树莓派4 性能大比拼:标准<b class='flag-5'>Linux</b>与实时<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>内核</b>的延迟测试

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-Linux设备驱动的分类

    设备和设备都映射到了虚拟文件系统目录下。应用程序可以通过系统调用接口open、close、write、read等相关API进行访问字符设备和设备,继而实现对硬件的操作。Linux
    发表于 03-12 10:20

    飞凌嵌入式ElfBoard ELF 1板卡-Linux设备驱动的分类

    设备和设备都映射到了虚拟文件系统目录下。应用程序可以通过系统调用接口open、close、write、read等相关API进行访问字符设备和设备,继而实现对硬件的操作。Linux
    发表于 03-10 17:00

    迅为RK3562开发板Android源码定制开发-kernel开发

    内核版本是 5.10.157 版本,内核默认的配置文件是 kernel-5.10/arch/arm64/configs/rockchip_defconfig 如果我们要使用图形化界面配置内核
    发表于 02-11 15:54

    升级centos7内核版本

    先查看当前内核版本 ~] #uname -a Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 1659
    的头像 发表于 01-02 10:41 1004次阅读