Documentation/translations/zh_CN/mm/mmu_notifier.rst
Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/mm/mmu_notifier.rst
File Facts
- System
- Linux kernel
- Corpus path
Documentation/translations/zh_CN/mm/mmu_notifier.rst- Extension
.rst- Size
- 3921 bytes
- Lines
- 98
- Domain
- Support Tooling And Documentation
- Bucket
- Documentation
- Inferred role
- Support Tooling And Documentation: documentation
- Status
- atlas-only
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
- No top-level syscall, struct, function, initcall, or export declaration detected by the generator.
Annotated Snippet
:Original: Documentation/mm/mmu_notifier.rst
:翻译:
司延腾 Yanteng Si <siyanteng@loongson.cn>
:校译:
什么时候需要页表锁内通知?
==========================
当清除一个pte/pmd时,我们可以选择通过在页表锁下(通知版的\*_clear_flush调用
mmu_notifier_invalidate_range)通知事件。但这种通知并不是在所有情况下都需要的。
对于二级TLB(非CPU TLB),如IOMMU TLB或设备TLB(当设备使用类似ATS/PASID的东西让
IOMMU走CPU页表来访问进程的虚拟地址空间)。只有两种情况需要在清除pte/pmd时在持有页
表锁的同时通知这些二级TLB:
A) 在mmu_notifier_invalidate_range_end()之前,支持页的地址被释放。
B) 一个页表项被更新以指向一个新的页面(COW,零页上的写异常,__replace_page(),...)。
情况A很明显,你不想冒风险让设备写到一个现在可能被一些完全不同的任务使用的页面。
情况B更加微妙。为了正确起见,它需要按照以下序列发生:
- 上页表锁
- 清除页表项并通知 ([pmd/pte]p_huge_clear_flush_notify())
- 设置页表项以指向新页
如果在设置新的pte/pmd值之前,清除页表项之后没有进行通知,那么你就会破坏设备的C11或
C++11等内存模型。
考虑以下情况(设备使用类似于ATS/PASID的功能)。
两个地址addrA和addrB,这样|addrA - addrB| >= PAGE_SIZE,我们假设它们是COW的
写保护(B的其他情况也适用)。
::
[Time N] --------------------------------------------------------------------
CPU-thread-0 {尝试写到addrA}
CPU-thread-1 {尝试写到addrB}
CPU-thread-2 {}
CPU-thread-3 {}
DEV-thread-0 {读取addrA并填充设备TLB}
DEV-thread-2 {读取addrB并填充设备TLB}
[Time N+1] ------------------------------------------------------------------
CPU-thread-0 {COW_step0: {mmu_notifier_invalidate_range_start(addrA)}}
CPU-thread-1 {COW_step0: {mmu_notifier_invalidate_range_start(addrB)}}
CPU-thread-2 {}
CPU-thread-3 {}
DEV-thread-0 {}
DEV-thread-2 {}
[Time N+2] ------------------------------------------------------------------
CPU-thread-0 {COW_step1: {更新页表以指向addrA的新页}}
CPU-thread-1 {COW_step1: {更新页表以指向addrB的新页}}
CPU-thread-2 {}
CPU-thread-3 {}
DEV-thread-0 {}
DEV-thread-2 {}
[Time N+3] ------------------------------------------------------------------
CPU-thread-0 {preempted}
CPU-thread-1 {preempted}
CPU-thread-2 {写入addrA,这是对新页面的写入}
CPU-thread-3 {}
DEV-thread-0 {}
DEV-thread-2 {}
[Time N+3] ------------------------------------------------------------------
Annotation
- Atlas domain: Support Tooling And Documentation / Documentation.
- Implementation status: atlas-only.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.