Documentation/translations/zh_CN/mm/hmm.rst
Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/mm/hmm.rst
File Facts
- System
- Linux kernel
- Corpus path
Documentation/translations/zh_CN/mm/hmm.rst- Extension
.rst- Size
- 19231 bytes
- Lines
- 356
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function driver_populate_range
Annotated Snippet
CPU pte 没有设置写权限,那么HMM将调用handle_mm_fault()。
hmm_range_fault 完成后,标志位被设置为页表的当前状态,即 HMM_PFN_VALID | 如果页
面可写,将设置 HMM_PFN_WRITE。
从核心内核的角度表示和管理设备内存
==================================
尝试了几种不同的设计来支持设备内存。第一个使用特定于设备的数据结构来保存有关迁移内存
的信息,HMM 将自身挂接到 mm 代码的各个位置,以处理对设备内存支持的地址的任何访问。
事实证明,这最终复制了 struct page 的大部分字段,并且还需要更新许多内核代码路径才
能理解这种新的内存类型。
大多数内核代码路径从不尝试访问页面后面的内存,而只关心struct page的内容。正因为如此,
HMM 切换到直接使用 struct page 用于设备内存,这使得大多数内核代码路径不知道差异。
我们只需要确保没有人试图从 CPU 端映射这些页面。
移入和移出设备内存
==================
由于 CPU 无法直接访问设备内存,因此设备驱动程序必须使用硬件 DMA 或设备特定的加载/存
储指令来迁移数据。migrate_vma_setup()、migrate_vma_pages() 和
migrate_vma_finalize() 函数旨在使驱动程序更易于编写并集中跨驱动程序的通用代码。
在将页面迁移到设备私有内存之前,需要创建特殊的设备私有 ``struct page`` 。这些将用
作特殊的“交换”页表条目,以便 CPU 进程在尝试访问已迁移到设备专用内存的页面时会发生异常。
这些可以通过以下方式分配和释放::
struct resource *res;
struct dev_pagemap pagemap;
res = request_free_mem_region(&iomem_resource, /* number of bytes */,
"name of driver resource");
pagemap.type = MEMORY_DEVICE_PRIVATE;
pagemap.range.start = res->start;
pagemap.range.end = res->end;
pagemap.nr_range = 1;
pagemap.ops = &device_devmem_ops;
memremap_pages(&pagemap, numa_node_id());
memunmap_pages(&pagemap);
release_mem_region(pagemap.range.start, range_len(&pagemap.range));
还有devm_request_free_mem_region(), devm_memremap_pages(),
devm_memunmap_pages() 和 devm_release_mem_region() 当资源可以绑定到 ``struct device``.
整体迁移步骤类似于在系统内存中迁移 NUMA 页面(see Documentation/mm/page_migration.rst) ,
但这些步骤分为设备驱动程序特定代码和共享公共代码:
1. ``mmap_read_lock()``
设备驱动程序必须将 ``struct vm_area_struct`` 传递给migrate_vma_setup(),
因此需要在迁移期间保留 mmap_read_lock() 或 mmap_write_lock()。
2. ``migrate_vma_setup(struct migrate_vma *args)``
设备驱动初始化了 ``struct migrate_vma`` 的字段,并将该指针传递给
migrate_vma_setup()。``args->flags`` 字段是用来过滤哪些源页面应该被迁移。
例如,设置 ``MIGRATE_VMA_SELECT_SYSTEM`` 将只迁移系统内存,设置
``MIGRATE_VMA_SELECT_DEVICE_PRIVATE`` 将只迁移驻留在设备私有内存中的页
面。如果后者被设置, ``args->pgmap_owner`` 字段被用来识别驱动所拥有的设备
私有页。这就避免了试图迁移驻留在其他设备中的设备私有页。目前,只有匿名的私有VMA
范围可以被迁移到系统内存和设备私有内存。
migrate_vma_setup()所做的第一步是用 ``mmu_notifier_invalidate_range_start()``
和 ``mmu_notifier_invalidate_range_end()`` 调用来遍历设备周围的页表,使
其他设备的MMU无效,以便在 ``args->src`` 数组中填写要迁移的PFN。
``invalidate_range_start()`` 回调传递给一个``struct mmu_notifier_range`` ,
Annotation
- Detected declarations: `function driver_populate_range`.
- 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.