PAT / MTRR / PTE 三者的关系与优先级

2025-10-30 7 0

PAT / MTRR / PTE 正是 ioremap_wc()、ioremap_cache() 等函数性能差异的底层原因

🧩三者的作用概览

名称 全称 层级 作用 典型设置接口
MTRR Memory Type Range Registers CPU 全局级 为物理地址范围指定内存类型(WB/WC/UC 等) BIOS、内核启动阶段 (/proc/mtrr)
PAT Page Attribute Table 每个 CPU 的全局表 定义 PTE 中 “memory type 编码” 的含义 内核初始化时设置(CR_PAT 寄存器)
PTE Page Table Entry 页表级 实际控制每个页的内存类型(通过 PAT + PWT/PCD 位编码) 通过 ioremap_*() 等接口

🧠三者关系示意图

            ┌────────────────────────┐
            │      内核驱动映射调用   │
            │  ioremap(), ioremap_wc()│
            └──────────┬─────────────┘
                       │
                       ▼
           ┌────────────────────────────┐
           │   PTE:页表项 (Page Table) │
           │  - PWT / PCD 位             │
           │  - PAT 位                   │
           └──────────┬─────────────────┘
                      │ 组合编码索引
                      ▼
           ┌────────────────────────────┐
           │      PAT:页属性表          │
           │  索引出内存类型(WB/WC/UC)│
           └──────────┬─────────────────┘
                      │
                      ▼
           ┌────────────────────────────┐
           │ MTRR:物理区间默认类型     │
           │ 供 PAT 覆盖或 fallback 使用 │
           └────────────────────────────┘

⚙️内存类型 (Memory Type) 对比

类型 含义 特性 用途
UC (Uncacheable) 不缓存 最慢,强制顺序访问 MMIO 寄存器
WC (Write Combining) 写合并 连续写合并为 burst,提高显存吞吐 GPU GDDR 映射
WT (Write Through) 写穿透 读缓存、写同时写内存 一般不用
WB (Write Back) 回写缓存 最快的普通内存类型 系统内存
WP (Write Protected) 只读缓存 特殊用途 调试或设备保护

🧩PTE 中的关键位

PTE 中有三个位控制缓存类型:

名称 含义
PCD Page Cache Disable 1 = 禁止缓存
PWT Page Write Through 1 = 写穿透模式
PAT Page Attribute Table 选择 PAT 表中不同组合的 entry

这三个位组成 3-bit 索引,共 8 种组合:

PAT PCD PWT 组合索引 默认类型(Intel 默认 PAT 表)
0 0 0 0 WB
0 0 1 1 WT
0 1 0 2 UC-
0 1 1 3 UC
1 0 0 4 WC
1 0 1 5 WP
1 1 0 6 UC
1 1 1 7 UC

注:Linux 初始化时会重新写入 PAT 表,使得 WC 支持更方便。

⚖️优先级规则

CPU 最终确定内存类型时的优先级是:

1️⃣ 固定 MTRR(Fixed MTRR)
2️⃣ 可变 MTRR(Variable MTRR)
3️⃣ PAT(通过 PTE 编码)

在多个机制同时定义时:

组合情况 最终结果
MTRR = UC 无论 PAT/PTE,最终 UC
MTRR = WB 且 PTE = WC 最终 WC
MTRR = WB 且 PTE = UC 最终 UC
无 MTRR 定义 使用 PAT 决定

也就是说:

  • MTRR 限制了物理区间的上限属性(全局);

  • PAT 决定每页的具体缓存策略(局部);

  • PTE 是 PAT 的载体。

🚀 与 ioremap_* 的对应关系

函数 设置的 PAT/PTE 位 结果类型 性能特征
ioremap() UC 不缓存 最慢、最安全
ioremap_nocache() UC (同上) 同上 已过时
ioremap_wc() PAT = 1 (WC) 写合并 适合 GPU 显存
ioremap_cache() WB 可缓存 普通 RAM 映射
ioremap_prot() 自定义 取决于保护属性 自定义用途

🧩 在 5.10+ 的优化背景

在 Linux 5.10+,ioremap_wc() 优化了 reserve_memtype() 的逻辑:

  • 过去每次 ioremap_wc() 都会申请和合并 MTRR 区域(开销大);

  • 新逻辑优先走 PAT-only 模式,不再频繁更新 MTRR;

  • 只在 BIOS 没有开启 PAT 支持时回退到 MTRR。

这显著减少了:

  • 全局锁 memtype_lock 的竞争;

  • 映射延迟;

  • CPU 占用。

✅总结

层级 控制范围 功能 示例
MTRR 物理区间全局 BIOS/固件设定默认类型 “BAR2 映射为 WC”
PAT CPU 层全局表 定义 PTE 编码的含义 PAT[4] = WC
PTE 每页设置 实际页表项,决定最终类型 ioremap_wc() 设置为 PAT=1

🧠 最终访问性能 = MTRR(限制) + PAT(解释) + PTE(指令)

ioremap 映射路径

相关文章

发布评论