目录

  • 初识 PageWalk 机制

  • PageWalk 通识知识

    • PGD(Page Global Directory)

    • P4D(Page 4th Directory)

    • PUD(Page Upper Directory)

    • PMD(Page Middle Directory)

    • PTE(Page Table Entry)

    • PGPROT(Page Table Attribute)

    • PageWalk 机制数据结构

    • PageWalk 机制源码解析

  • PageWalk 机制实践

  • PageWalk 机制使用

    • 遍历内核空间虚拟内存页表

    • 遍历用户空间虚拟内存页表

    • 遍历用户空间整个 VMA 页表

    • 遍历文件映射 PageCACHE 的页表

    • 遍历用户空间 Anonymous 映射内存页表

    • 遍历用户空间 File 映射内存页表

    • 遍历用户空间 Hugetlbfs Hugepage 内存页表

    • 遍历用户空间 Transport Hugepage 内存页表

    • 遍历用户空间 MMIO 页表

    • 遍历用户空间 RSVDMEM 页表

    • 遍历内核空间 VMALLOC 映射内存页表

    • 遍历内核空间永久映射内存页表

    • 遍历内核空间线性映射内存页表

    • 遍历内核空间临时映射内存页表

    • 遍历内核空间 IOREMAP 映射的 MMIO

    • 遍历映射 CMA 内存页表

    • 遍历映射 DMA 内存页表

    • 修改/更新页表

    • 新增/填充/删除页表

  • PageWalk 应用场景

    • SMAPs 场景: /proc/pid/smaps

    • NUMA_MAPS 场景: /proc/pid/numa_maps

    • Pagemap 场景: /proc/pid/pagemap

    • Clear Reference 场景: /proc/pid/clear_refs

    • Madvise: MADV_COLD 场景

    • Madvise: MADV_PAGEOUT 场景

    • Madvise: MADV_FREE 场景

    • Madvise: MADV_WILLNEED 场景

    • MLOCK 场景

  • Case by Case

    • walk_page_test

    • __walk_page_range

    • walk_pmd_range

    • walk_pte_range

  • PageWalk 进阶研究

    • mmap_lock 问题

    • pte_entry 上锁问题

    • 无锁访问页表研究

    • page_walk_action 功能

    • PageWalk 导致 Split THP 研究

图片无法显示,请右键点击新窗口打开图片


PageWalk 通识知识

在 Linux 里,每个进程都包含独立连续的线性空间,该空间被划分成两部分,其中一部分是进程使用的空间称用户空间地址空间,其为进程运行提供了运行所需的内存; 另外一部分是内核使用的空间称为内核地址空间。进程的线性空间包含虚拟内存,虚拟内存只有建立了页表映射到物理内存上,那么进程才能使用这段虚拟内存,否则会引起页面故障.

PageWalk 机制: Linux 内核提供用于页表遍历和页表修改的机制,可以对用户空间的虚拟内存或者内核空间虚拟内存,进行页表查询和页表修改。在 Linux 中,其最新的内核支持 5 级页表,分别是 PGD(Page Global Directory) 页表P4D(Page 4th Directory) 页表PUD(Page Upper Directory) 页表PMD(Page Middle Directory) 页表PTE(Page Table) 页表。Linux 采用这 5 级页表屏蔽了不同架构硬件页表之间的差异,统一采用 Linux 5 级页表进行管理。PageWalk 机制就是建立在 Linux 5 级页表之上的页表查询和页表修改.

PageWalk 机制 实现很精简,其就是遍历每一级页表,首先检查对应的 Entry 是否为空,如果是空那么就是调用 hole 相关的回调; 反之页表不为空,那么就会 Entry 进行访问或者修改, 接下来确认是否继续遍历下一级页表,如果是那么进入下一级页表继续之前的操作; 如果不继续遍历下一级页表,那么此时刷新 TLB,使最新的页表 Entry 更新到 TLB 里,最终完成遍历。PageWalk 机制 提供了一个遍历页表的机制,然后调用者可以根据需要选择特定的页表.

PageWalk 数据结构

PageWalk 机制 提供了 struct mm_walk_ops 数据结构,其内包含很多回调函数,调用者需要在哪一级页表操作,那么就实现该数据结构的成员即可,例如需要修改 PMD 页表,那么只需实现该数据结构的 pmd_entry 成员即可,当 PageWalk 机制遍历到 PMD 页表时,就会调用 pmd_entry 成员指向的回调函数. 其他成员的含义是:

图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

图片无法显示,请右键点击新窗口打开图片