土法炼钢兴趣小组的算法知识备份

【操作系统百科】x86_64 多级页表

文章导航

分类入口
os
标签入口
#paging#pml4#pcid#la57#cr3

目录

一、先看图

flowchart LR
    VA[48/57 位 VA] --> PML5[PML5E<br/>LA57 开启]
    PML5 --> PML4[PML4E]
    PML4 --> PDPT[PDPTE<br/>1G page 可停]
    PDPT --> PD[PDE<br/>2M page 可停]
    PD --> PT[PTE<br/>4K]
    PT --> PA[物理地址]
    CR3[CR3 寄存器] --> PML4
    classDef reg fill:#a371f722,stroke:#a371f7,color:#adbac7;
    classDef tbl fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    class CR3 reg
    class PML5,PML4,PDPT,PD,PT tbl

二、4 级分页(默认 48 位 VA)

VA 被切成 9+9+9+9+12:

bit  47..39  38..30  29..21  20..12  11..0
     PML4    PDPT    PD      PT      偏移

每级 512 项 × 8 字节 = 4KB 一页(正好一个 page)。走 4 次内存解析一个 VA,MMU 硬件做,称 page walk。

CR3 指向当前进程的 PML4 物理地址;切换地址空间就是换 CR3。

三、5 级分页 LA57

2017 Ice Lake 开始硬件支持 57 位 VA(128PB)。上面多一级 PML5。需要:

查看:grep la57 /proc/cpuinfo

四、大页停止

PDE 的 PSE bit=1 → 这一项不是再下一级表,而是直接 2MB 物理页。PDPTE 同理停 1GB。

所以 x86_64 页大小有 4K / 2M / 1G 三档。huge page 提高 TLB 命中、减少 page walk 成本。

五、PTE 的关键 bit

63      62..52  51..12       11..9 8 7   6 5 4 3 2 1 0
NX      SW/MPK  PA[51..12]   SW    G PAT D A PCD PWT U/S R/W P

六、CR3 切换

一次 fork/exec 后任务切换:

mov %rax, %cr3    # rax = 新 mm->pgd 物理地址

副作用:刷光所有非-global TLB 项。这是进程切换最大开销之一。

七、PCID:TLB 按地址空间标签化

无 PCID 时每次换 CR3 都清 TLB。启用 PCID 后 CR3 低 12 bit 存 12-bit PCID,TLB 按 (PCID, VA) 查,换进程不用清

Linux 4.14+ 默认启用(X86_FEATURE_PCID),每进程分配 PCID(12 bit 所以只 4096 个,循环用)。

INVPCID

专门无效化某个 PCID 的 TLB 条目:

invpcid_flush_single_context(pcid);
invpcid_flush_single_addr(pcid, va);
invpcid_flush_all_nonglobals();

PTI(KPTI)把用户/内核地址空间分开两份页表 → PCID 的价值翻倍。

八、硬件 page walker 与 MMU cache

MMU 不只缓存 TLB,还缓存上层页表项:Paging-structure caches。

所以即使 TLB miss,只要走到”第二级”就能命中上层缓存,省 2-3 次内存。

4 级 walk 若全 miss 要读 4 次 RAM(每次 ~100ns)= ~400ns 纯翻译开销。这是为什么 huge page + Intel ERMS 对某些负载立竿见影。

九、硬件辅助特性

查看:/proc/cpuinfoflags,关注 smep smap pcid invpcid la57 pku

十、页表内存开销

一个进程 ≈ 多少页表内存?

工作集 >100GB 的 DB 不用 huge page 能卡在 TLB 和 page table 开销上。

十一、观察

# 看进程页表大小
grep VmPTE /proc/$$/status

# 看 CPU 特性
grep -oE 'la57|pcid|invpcid|pku|smep|smap|nx' /proc/cpuinfo | sort -u

# x86 raw PTE dump(需 crash/drgn)
drgn -c /proc/kcore -e 'print(find_task(1234).mm.pgd)'

十二、常见坑

A:Transparent PKU / MPK 混用时 fork 后子进程 pkey 可能丢——glibc 2.38+ 有改进 B:LA57 + 老 JIT:某些 JIT 假设 VA 高位 0,越界就崩 C:容器里 PCID/INVPCID 一般能用,但某些老 hypervisor 不透传

十三、小结


参考文献

工具


上一篇虚拟内存模型 下一篇ARMv8 VMSA 页表

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-05-06 · os

【操作系统百科】内核内存调试

内核内存 bug 是最难追的:UAF、OOB、double free、leak 都可能沉默数月。本文讲 KASAN 三种模式、KFENCE 生产采样、kmemleak、SLUB_DEBUG、UBSAN/KCSAN 联动。

2026-05-08 · os

【操作系统百科】VFS 四层抽象

Linux 的一切皆文件靠 VFS 实现——superblock、inode、dentry、file 四层抽象加 ops 表。本文讲 VFS 核心数据结构、dcache、inode cache、RCU lookup,以及文件系统如何插入 VFS。

2026-04-22 · os

操作系统百科

Linux 6.x 视角下的操作系统系列索引:110 篇覆盖调度、虚拟内存、文件系统与 I/O、并发、隔离、可观测性,按主题、阅读路径与关键问题三种入口组织。

2026-05-27 · os

【操作系统百科】用户态分配器:jemalloc vs tcmalloc

jemalloc 与 tcmalloc 都想解决多线程分配器的老问题:锁争抢、碎片、RSS 膨胀与回收抖动。但两者把优化重点放在了不同位置:tcmalloc 更激进地把热路径推到 per-CPU,jemalloc 则把 arena、extent、decay 和 profiling 做成了一套更完整的内存治理工具箱。


By .