Bsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/mm/physical_memorymodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/zh_TW/mm/physical_memorymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/it_IT/mm/physical_memorymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/ja_JP/mm/physical_memorymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/ko_KR/mm/physical_memorymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/pt_BR/mm/physical_memorymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/sp_SP/mm/physical_memorymodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhS/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/mm/physical_memory.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h%Documentation/mm/physical_memory.rst h]h)}(h$Documentation/mm/physical_memory.rsth]h$Documentation/mm/physical_memory.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhKubj)}(h-王亚鑫 Yaxin Wang h]h)}(h,王亚鑫 Yaxin Wang h](h王亚鑫 Yaxin Wang <}(hj4hhhNhNubh reference)}(hwang.yaxin@zte.com.cnh]hwang.yaxin@zte.com.cn}(hj>hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:wang.yaxin@zte.com.cnuh1j<hj4ubh>}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hj0ubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h 物理内存h]h 物理内存}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1johjlhhhhhK ubh)}(hLinux可用于多种架构,因此需要一个与架构无关的抽象来表示物理内存。本章描述 了管理运行系统中物理内存的结构。h]hLinux可用于多种架构,因此需要一个与架构无关的抽象来表示物理内存。本章描述 了管理运行系统中物理内存的结构。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(h第一个与内存管理相关的主要概念是 `非一致性内存访问(NUMA) `h](h1第一个与内存管理相关的主要概念是 }(hjhhhNhNubhtitle_reference)}(hZ`非一致性内存访问(NUMA) `h]hX非一致性内存访问(NUMA) }(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hX%在多核和多插槽机器中,内存可能被组织成不同的存储区,这些存储区根据与处理器 的距离“不同”而有不同的访问开销。例如,可能为每个CPU分配内存存储区,或者为 外围设备在附近分配一个非常适合DMA的内存存储区。h]hX%在多核和多插槽机器中,内存可能被组织成不同的存储区,这些存储区根据与处理器 的距离“不同”而有不同的访问开销。例如,可能为每个CPU分配内存存储区,或者为 外围设备在附近分配一个非常适合DMA的内存存储区。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hX(每个存储区被称为一个节点,节点在Linux中表示为 ``struct pglist_data``, 即使是在UMA架构中也是这样表示。该结构总是通过 ``pg_data_t`` 来引用。特 定节点的 ``pg_data_t`` 结构体可以通过NODE_DATA(nid)引用,其中nid被称 为该节点的ID。h](hB每个存储区被称为一个节点,节点在Linux中表示为 }(hjhhhNhNubhliteral)}(h``struct pglist_data``h]hstruct pglist_data}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhG, 即使是在UMA架构中也是这样表示。该结构总是通过 }(hjhhhNhNubj)}(h ``pg_data_t``h]h pg_data_t}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 来引用。特 定节点的 }(hjhhhNhNubj)}(h ``pg_data_t``h]h pg_data_t}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhQ 结构体可以通过NODE_DATA(nid)引用,其中nid被称 为该节点的ID。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hXz对于非一致性内存访问(NUMA)架构,节点数据结构在引导时由特定于架构的代码早 期分配。通常,这些结构在其所在的内存区上本地分配。对于一致性内存访问(UMA) 架构,只使用一个静态的 ``pg_data_t`` 结构体,称为 ``contig_page_data``。 节点将会在 :ref:`节点 ` 章节中进一步讨论。h](hX对于非一致性内存访问(NUMA)架构,节点数据结构在引导时由特定于架构的代码早 期分配。通常,这些结构在其所在的内存区上本地分配。对于一致性内存访问(UMA) 架构,只使用一个静态的 }(hjhhhNhNubj)}(h ``pg_data_t``h]h pg_data_t}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 结构体,称为 }(hjhhhNhNubj)}(h``contig_page_data``h]hcontig_page_data}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh。 节点将会在 }(hjhhhNhNubh)}(h:ref:`节点 `h]hinline)}(hj-h]h节点}(hj1hhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1j/hj+ubah}(h]h ]h"]h$]h&]refdoc%translations/zh_CN/mm/physical_memory refdomainj<reftyperef refexplicitrefwarn reftargetnodesuh1hhhhKhjubh 章节中进一步讨论。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hXW整个物理内存被划分为一个或多个被称为区域的块,这些区域表示内存的范围。这 些范围通常由访问内存的架构限制来决定。在节点内,与特定区域对应的内存范围 由 ``struct zone`` 结构体描述,该结构被定义为 ``zone_t``,每种区域都 属于以下描述类型的一种。h](h整个物理内存被划分为一个或多个被称为区域的块,这些区域表示内存的范围。这 些范围通常由访问内存的架构限制来决定。在节点内,与特定区域对应的内存范围 由 }(hjZhhhNhNubj)}(h``struct zone``h]h struct zone}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjZubh) 结构体描述,该结构被定义为 }(hjZhhhNhNubj)}(h ``zone_t``h]hzone_t}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1jhjZubh7,每种区域都 属于以下描述类型的一种。}(hjZhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK#hjlhhubh bullet_list)}(hhh]h list_item)}(hX``ZONE_DMA`` 和 ``ZONE_DMA32`` 在历史上代表适用于DMA的内存,这些 内存由那些不能访问所有可寻址内存的外设访问。多年来,已经有了更好、更稳 固的接口来获取满足特定DMA需求的内存(这些接口由 Documentation/core-api/dma-api.rst 文档描述),但是 ``ZONE_DMA`` 和 ``ZONE_DMA32`` 仍然表示访问受限的内存范围。 h]h)}(hX``ZONE_DMA`` 和 ``ZONE_DMA32`` 在历史上代表适用于DMA的内存,这些 内存由那些不能访问所有可寻址内存的外设访问。多年来,已经有了更好、更稳 固的接口来获取满足特定DMA需求的内存(这些接口由 Documentation/core-api/dma-api.rst 文档描述),但是 ``ZONE_DMA`` 和 ``ZONE_DMA32`` 仍然表示访问受限的内存范围。h](j)}(h ``ZONE_DMA``h]hZONE_DMA}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 和 }(hjhhhNhNubj)}(h``ZONE_DMA32``h]h ZONE_DMA32}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX 在历史上代表适用于DMA的内存,这些 内存由那些不能访问所有可寻址内存的外设访问。多年来,已经有了更好、更稳 固的接口来获取满足特定DMA需求的内存(这些接口由 Documentation/core-api/dma-api.rst 文档描述),但是 }(hjhhhNhNubj)}(h ``ZONE_DMA``h]hZONE_DMA}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 和 }(hjhhhNhNubj)}(h``ZONE_DMA32``h]h ZONE_DMA32}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ 仍然表示访问受限的内存范围。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK(hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubah}(h]h ]h"]h$]h&]bullet*uh1jhhhK(hjlhhubh)}(h取决于架构的不同,这两种区域可以在构建时通过关闭 ``CONFIG_ZONE_DMA`` 和 ``CONFIG_ZONE_DMA32`` 配置选项来禁用。一些64位的平台可能需要这两种区域, 因为他们支持具有不同DMA寻址限制的外设。h](hI取决于架构的不同,这两种区域可以在构建时通过关闭 }(hjhhhNhNubj)}(h``CONFIG_ZONE_DMA``h]hCONFIG_ZONE_DMA}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 和 }(hjhhhNhNubj)}(h``CONFIG_ZONE_DMA32``h]hCONFIG_ZONE_DMA32}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 配置选项来禁用。一些64位的平台可能需要这两种区域, 因为他们支持具有不同DMA寻址限制的外设。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK.hjlhhubj)}(hhh](j)}(h``ZONE_NORMAL`` 是普通内存的区域,这种内存可以被内核随时访问。如果DMA 设备支持将数据传输到所有可寻址的内存区域,那么可在该区域的页面上执行DMA 操作。``ZONE_NORMAL`` 总是开启的。 h]h)}(h``ZONE_NORMAL`` 是普通内存的区域,这种内存可以被内核随时访问。如果DMA 设备支持将数据传输到所有可寻址的内存区域,那么可在该区域的页面上执行DMA 操作。``ZONE_NORMAL`` 总是开启的。h](j)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0ubh 是普通内存的区域,这种内存可以被内核随时访问。如果DMA 设备支持将数据传输到所有可寻址的内存区域,那么可在该区域的页面上执行DMA 操作。}(hj0hhhNhNubj)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0ubh 总是开启的。}(hj0hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK2hj,ubah}(h]h ]h"]h$]h&]uh1jhj)hhhhhNubj)}(h``ZONE_HIGHMEM`` 是指那些没有在内核页表中永久映射的物理内存部分。该区 域的内存只能通过临时映射被内核访问。该区域只在某些32位架构上可用,并且是 通过 ``CONFIG_HIGHMEM`` 选项开启。 h]h)}(h``ZONE_HIGHMEM`` 是指那些没有在内核页表中永久映射的物理内存部分。该区 域的内存只能通过临时映射被内核访问。该区域只在某些32位架构上可用,并且是 通过 ``CONFIG_HIGHMEM`` 选项开启。h](j)}(h``ZONE_HIGHMEM``h]h ZONE_HIGHMEM}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhubh 是指那些没有在内核页表中永久映射的物理内存部分。该区 域的内存只能通过临时映射被内核访问。该区域只在某些32位架构上可用,并且是 通过 }(hjhhhhNhNubj)}(h``CONFIG_HIGHMEM``h]hCONFIG_HIGHMEM}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhubh 选项开启。}(hjhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK6hjdubah}(h]h ]h"]h$]h&]uh1jhj)hhhhhNubj)}(hX^``ZONE_MOVABLE`` 是指可访问的普通内存区域,就像 ``ZONE_NORMAL`` 一样。不同之处在于 ``ZONE_MOVABLE`` 中的大多数页面内容是可移动的。 这意味着这些页面的虚拟地址不会改变,但它们的内容可能会在不同的物理页面 之间移动。通常,在内存热插拔期间填充 ``ZONE_MOVABLE``,在启动时也可 以使用 ``kernelcore``、``movablecore`` 和 ``movable_node`` 这些内核命令行参数来填充。更多详细信息,请参阅内核文档 Documentation/mm/page_migration.rst 和 Documentation/admin-guide/mm/memory-hotplug.rst。 h]h)}(hX]``ZONE_MOVABLE`` 是指可访问的普通内存区域,就像 ``ZONE_NORMAL`` 一样。不同之处在于 ``ZONE_MOVABLE`` 中的大多数页面内容是可移动的。 这意味着这些页面的虚拟地址不会改变,但它们的内容可能会在不同的物理页面 之间移动。通常,在内存热插拔期间填充 ``ZONE_MOVABLE``,在启动时也可 以使用 ``kernelcore``、``movablecore`` 和 ``movable_node`` 这些内核命令行参数来填充。更多详细信息,请参阅内核文档 Documentation/mm/page_migration.rst 和 Documentation/admin-guide/mm/memory-hotplug.rst。h](j)}(h``ZONE_MOVABLE``h]h ZONE_MOVABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh/ 是指可访问的普通内存区域,就像 }(hjhhhNhNubj)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 一样。不同之处在于 }(hjhhhNhNubj)}(h``ZONE_MOVABLE``h]h ZONE_MOVABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 中的大多数页面内容是可移动的。 这意味着这些页面的虚拟地址不会改变,但它们的内容可能会在不同的物理页面 之间移动。通常,在内存热插拔期间填充 }(hjhhhNhNubj)}(h``ZONE_MOVABLE``h]h ZONE_MOVABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh ,在启动时也可 以使用 }(hjhhhNhNubj)}(h``kernelcore``h]h kernelcore}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh、}(hjhhhNhNubj)}(h``movablecore``h]h movablecore}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 和 }(hjhhhNhNubj)}(h``movable_node``h]h movable_node}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 这些内核命令行参数来填充。更多详细信息,请参阅内核文档 Documentation/mm/page_migration.rst 和 Documentation/admin-guide/mm/memory-hotplug.rst。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK:hjubah}(h]h ]h"]h$]h&]uh1jhj)hhhhhNubj)}(hXe``ZONE_DEVICE`` 表示位于持久性内存(PMEM)和图形处理单元(GPU) 等设备上的内存。它与RAM区域类型有不同的特性,并且它的存在是为了提供 :ref:`struct page` 结构和内存映射服务,以便设备驱动程序能 识别物理地址范围。``ZONE_DEVICE`` 通过 ``CONFIG_ZONE_DEVICE`` 选项开启。 h]h)}(hXd``ZONE_DEVICE`` 表示位于持久性内存(PMEM)和图形处理单元(GPU) 等设备上的内存。它与RAM区域类型有不同的特性,并且它的存在是为了提供 :ref:`struct page` 结构和内存映射服务,以便设备驱动程序能 识别物理地址范围。``ZONE_DEVICE`` 通过 ``CONFIG_ZONE_DEVICE`` 选项开启。h](j)}(h``ZONE_DEVICE``h]h ZONE_DEVICE}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2ubh 表示位于持久性内存(PMEM)和图形处理单元(GPU) 等设备上的内存。它与RAM区域类型有不同的特性,并且它的存在是为了提供 }(hj2hhhNhNubh)}(h:ref:`struct page`h]j0)}(hjJh]h struct page}(hjLhhhNhNubah}(h]h ](j;stdstd-refeh"]h$]h&]uh1j/hjHubah}(h]h ]h"]h$]h&]refdocjH refdomainjVreftyperef refexplicitrefwarnjNpagesuh1hhhhKChj2ubhV 结构和内存映射服务,以便设备驱动程序能 识别物理地址范围。}(hj2hhhNhNubj)}(h``ZONE_DEVICE``h]h ZONE_DEVICE}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2ubh 通过 }(hj2hhhNhNubj)}(h``CONFIG_ZONE_DEVICE``h]hCONFIG_ZONE_DEVICE}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2ubh 选项开启。}(hj2hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKChj.ubah}(h]h ]h"]h$]h&]uh1jhj)hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhK2hjlhhubh)}(h需要注意的是,许多内核操作只能使用 ``ZONE_NORMAL`` 来执行,因此它是 性能最关键区域。区域在 :ref:`区域 ` 章节中有更详细的讨论。h](h4需要注意的是,许多内核操作只能使用 }(hjhhhNhNubj)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh< 来执行,因此它是 性能最关键区域。区域在 }(hjhhhNhNubh)}(h:ref:`区域 `h]j0)}(hjh]h区域}(hjhhhNhNubah}(h]h ](j;stdstd-refeh"]h$]h&]uh1j/hjubah}(h]h ]h"]h$]h&]refdocjH refdomainjreftyperef refexplicitrefwarnjNzonesuh1hhhhKIhjubh" 章节中有更详细的讨论。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKIhjlhhubh)}(h节点和区域范围之间的关系由固件报告的物理内存映射决定,另外也由内存寻址 的架构约束以及内核命令行中的某些参数决定。h]h节点和区域范围之间的关系由固件报告的物理内存映射决定,另外也由内存寻址 的架构约束以及内核命令行中的某些参数决定。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjlhhubh)}(h例如,在具有2GB RAM的x86统一内存架构(UMA)机器上运行32位内核时,整 个内存将位于节点0,并且将有三个区域: ``ZONE_DMA``、 ``ZONE_NORMAL`` 和 ``ZONE_HIGHMEM``::h](h例如,在具有2GB RAM的x86统一内存架构(UMA)机器上运行32位内核时,整 个内存将位于节点0,并且将有三个区域: }(hjhhhNhNubj)}(h ``ZONE_DMA``h]hZONE_DMA}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh、 }(hjhhhNhNubj)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 和 }(hjhhhNhNubj)}(h``ZONE_HIGHMEM``h]h ZONE_HIGHMEM}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKOhjlhhubh literal_block)}(hX0 2G +-------------------------------------------------------------+ | node 0 | +-------------------------------------------------------------+ 0 16M 896M 2G +----------+-----------------------+--------------------------+ | ZONE_DMA | ZONE_NORMAL | ZONE_HIGHMEM | +----------+-----------------------+--------------------------+h]hX0 2G +-------------------------------------------------------------+ | node 0 | +-------------------------------------------------------------+ 0 16M 896M 2G +----------+-----------------------+--------------------------+ | ZONE_DMA | ZONE_NORMAL | ZONE_HIGHMEM | +----------+-----------------------+--------------------------+}hj:sbah}(h]h ]h"]h$]h&]hhuh1j8hhhKShjlhhubh)}(hX0在内核构建时关闭 ``ZONE_DMA`` 开启 ``ZONE_DMA32``,并且具有16GB RAM平均分配在两个节点上的arm64机器上,使用 ``movablecore=80%`` 参数 启动时,``ZONE_DMA32``、``ZONE_NORMAL`` 和 ``ZONE_MOVABLE`` 位于节点0,而 ``ZONE_NORMAL`` 和 ``ZONE_MOVABLE`` 位于节点1::h](h在内核构建时关闭 }(hjHhhhNhNubj)}(h ``ZONE_DMA``h]hZONE_DMA}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 开启 }(hjHhhhNhNubj)}(h``ZONE_DMA32``h]h ZONE_DMA32}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubhP,并且具有16GB RAM平均分配在两个节点上的arm64机器上,使用 }(hjHhhhNhNubj)}(h``movablecore=80%``h]hmovablecore=80%}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 参数 启动时,}(hjHhhhNhNubj)}(h``ZONE_DMA32``h]h ZONE_DMA32}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh、}(hjHhhhNhNubj)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 和 }(hjHhhhNhNubj)}(h``ZONE_MOVABLE``h]h ZONE_MOVABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 位于节点0,而 }(hjHhhhNhNubj)}(h``ZONE_NORMAL``h]h ZONE_NORMAL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 和 }hjHsbj)}(h``ZONE_MOVABLE``h]h ZONE_MOVABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 位于节点1:}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK^hjlhhubj9)}(hX 1G 9G 17G +--------------------------------+ +--------------------------+ | node 0 | | node 1 | +--------------------------------+ +--------------------------+ 1G 4G 4200M 9G 9320M 17G +---------+----------+-----------+ +------------+-------------+ | DMA32 | NORMAL | MOVABLE | | NORMAL | MOVABLE | +---------+----------+-----------+ +------------+-------------+h]hX 1G 9G 17G +--------------------------------+ +--------------------------+ | node 0 | | node 1 | +--------------------------------+ +--------------------------+ 1G 4G 4200M 9G 9320M 17G +---------+----------+-----------+ +------------+-------------+ | DMA32 | NORMAL | MOVABLE | | NORMAL | MOVABLE | +---------+----------+-----------+ +------------+-------------+}hjsbah}(h]h ]h"]h$]h&]hhuh1j8hhhKdhjlhhubh)}(h内存存储区可能位于交错的节点。在下面的例子中,一台x86机器有16GB的RAM分 布在4个内存存储区上,偶数编号的内存存储区属于节点0,奇数编号的内存条属于 节点1::h]h内存存储区可能位于交错的节点。在下面的例子中,一台x86机器有16GB的RAM分 布在4个内存存储区上,偶数编号的内存存储区属于节点0,奇数编号的内存条属于 节点1:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjlhhubj9)}(hX0 4G 8G 12G 16G +-------------+ +-------------+ +-------------+ +-------------+ | node 0 | | node 1 | | node 0 | | node 1 | +-------------+ +-------------+ +-------------+ +-------------+ 0 16M 4G +-----+-------+ +-------------+ +-------------+ +-------------+ | DMA | DMA32 | | NORMAL | | NORMAL | | NORMAL | +-----+-------+ +-------------+ +-------------+ +-------------+h]hX0 4G 8G 12G 16G +-------------+ +-------------+ +-------------+ +-------------+ | node 0 | | node 1 | | node 0 | | node 1 | +-------------+ +-------------+ +-------------+ +-------------+ 0 16M 4G +-----+-------+ +-------------+ +-------------+ +-------------+ | DMA | DMA32 | | NORMAL | | NORMAL | | NORMAL | +-----+-------+ +-------------+ +-------------+ +-------------+}hjsbah}(h]h ]h"]h$]h&]hhuh1j8hhhKshjlhhubh)}(hu在这种情况下,节点0将覆盖从0到12GB的内存范围,而节点1将覆盖从4GB到16GB 的内存范围。h]hu在这种情况下,节点0将覆盖从0到12GB的内存范围,而节点1将覆盖从4GB到16GB 的内存范围。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK}hjlhhubhtarget)}(h.. _nodes_zh_CN:h]h}(h]h ]h"]h$]h&]refid nodes-zh-cnuh1jhKhjlhhhhubjk)}(hhh](jp)}(h节点h]h节点}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1johj,hhhhhKubh)}(hX正如我们所提到的,内存中的每个节点由 ``pg_data_t`` 描述,通过 ``struct pglist_data`` 结构体的类型定义。在分配页面时,默认情况下,Linux 使用节点本地分配策略,从离当前运行CPU的最近节点分配内存。由于进程倾向于在同 一个CPU上运行,很可能会使用当前节点的内存。分配策略可以由用户控制,如内核文 档 Documentation/admin-guide/mm/numa_memory_policy.rst 中所述。h](h7正如我们所提到的,内存中的每个节点由 }(hj=hhhNhNubj)}(h ``pg_data_t``h]h pg_data_t}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubh 描述,通过 }(hj=hhhNhNubj)}(h``struct pglist_data``h]hstruct pglist_data}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubhXm 结构体的类型定义。在分配页面时,默认情况下,Linux 使用节点本地分配策略,从离当前运行CPU的最近节点分配内存。由于进程倾向于在同 一个CPU上运行,很可能会使用当前节点的内存。分配策略可以由用户控制,如内核文 档 Documentation/admin-guide/mm/numa_memory_policy.rst 中所述。}(hj=hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(hX大多数NUMA(非统一内存访问)架构维护了一个指向节点结构的指针数组。这些实际 的结构在启动过程中的早期被分配,这时特定于架构的代码解析了固件报告的物理内 存映射。节点初始化的大部分工作是在由free_area_init()实现的启动过程之后 完成,该函数在后面的小节 :ref:`初始化 ` 中有详细描述。h](hXe大多数NUMA(非统一内存访问)架构维护了一个指向节点结构的指针数组。这些实际 的结构在启动过程中的早期被分配,这时特定于架构的代码解析了固件报告的物理内 存映射。节点初始化的大部分工作是在由free_area_init()实现的启动过程之后 完成,该函数在后面的小节 }(hjohhhNhNubh)}(h!:ref:`初始化 `h]j0)}(hjyh]h 初始化}(hj{hhhNhNubah}(h]h ](j;stdstd-refeh"]h$]h&]uh1j/hjwubah}(h]h ]h"]h$]h&]refdocjH refdomainjreftyperef refexplicitrefwarnjNinitializationuh1hhhhKhjoubh 中有详细描述。}(hjohhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h除了节点结构,内核还维护了一个名为 ``node_states`` 的 ``nodemask_t`` 位掩码数组。这个数组中的每个位掩码代表一组特定属性的节点,这些属性由 ``enum node_states`` 定义,定义如下:h](h4除了节点结构,内核还维护了一个名为 }(hjhhhNhNubj)}(h``node_states``h]h node_states}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 的 }(hjhhhNhNubj)}(h``nodemask_t``h]h nodemask_t}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhh 位掩码数组。这个数组中的每个位掩码代表一组特定属性的节点,这些属性由 }(hjhhhNhNubj)}(h``enum node_states``h]henum node_states}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 定义,定义如下:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h3``N_POSSIBLE`` 节点可能在某个时刻上线。h](j)}(h``N_POSSIBLE``h]h N_POSSIBLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh% 节点可能在某个时刻上线。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h"``N_ONLINE`` 节点已经上线。h](j)}(h ``N_ONLINE``h]hN_ONLINE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 节点已经上线。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h/``N_NORMAL_MEMORY`` 节点拥有普通内存。h](j)}(h``N_NORMAL_MEMORY``h]hN_NORMAL_MEMORY}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 节点拥有普通内存。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h``N_HIGH_MEMORY`` 节点拥有普通或高端内存。当关闭 ``CONFIG_HIGHMEM`` 配置时, 也可以称为 ``N_NORMAL_MEMORY``。h](j)}(h``N_HIGH_MEMORY``h]h N_HIGH_MEMORY}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9ubh/ 节点拥有普通或高端内存。当关闭 }(hj9hhhNhNubj)}(h``CONFIG_HIGHMEM``h]hCONFIG_HIGHMEM}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9ubh 配置时, 也可以称为 }(hj9hhhNhNubj)}(h``N_NORMAL_MEMORY``h]hN_NORMAL_MEMORY}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9ubh。}(hj9hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(hC``N_MEMORY`` 节点拥有(普通、高端、可移动)内存。h](j)}(h ``N_MEMORY``h]hN_MEMORY}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjyubh7 节点拥有(普通、高端、可移动)内存。}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h+``N_CPU`` 节点拥有一个或多个CPU。h](j)}(h ``N_CPU``h]hN_CPU}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh" 节点拥有一个或多个CPU。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(hu对于具有上述属性的每个节点,``node_states[]`` 掩码中对应于节点ID的位会被置位。h](h*对于具有上述属性的每个节点,}(hjhhhNhNubj)}(h``node_states[]``h]hnode_states[]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh0 掩码中对应于节点ID的位会被置位。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(hN例如,对于具有常规内存和CPU的节点2,第二个bit将被设置::h]hM例如,对于具有常规内存和CPU的节点2,第二个bit将被设置:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubj9)}(hnode_states[N_POSSIBLE] node_states[N_ONLINE] node_states[N_NORMAL_MEMORY] node_states[N_HIGH_MEMORY] node_states[N_MEMORY] node_states[N_CPU]h]hnode_states[N_POSSIBLE] node_states[N_ONLINE] node_states[N_NORMAL_MEMORY] node_states[N_HIGH_MEMORY] node_states[N_MEMORY] node_states[N_CPU]}hjsbah}(h]h ]h"]h$]h&]hhuh1j8hhhKhj,hhubh)}(hn有关使用节点掩码(nodemasks)可能进行的各种操作,请参考 ``include/linux/nodemask.h``。h](hO有关使用节点掩码(nodemasks)可能进行的各种操作,请参考 }(hjhhhNhNubj)}(h``include/linux/nodemask.h``h]hinclude/linux/nodemask.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(h除此之外,节点掩码(nodemasks)提供用于遍历节点的宏,即 ``for_each_node()`` 和 ``for_each_online_node()``。h](hO除此之外,节点掩码(nodemasks)提供用于遍历节点的宏,即 }(hj hhhNhNubj)}(h``for_each_node()``h]hfor_each_node()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 和 }(hj hhhNhNubj)}(h``for_each_online_node()``h]hfor_each_online_node()}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubh)}(hJ例如,要为每个在线节点调用函数 foo(),可以这样操作::h]hI例如,要为每个在线节点调用函数 foo(),可以这样操作:}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj,hhubj9)}(hofor_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); foo(pgdat); }h]hofor_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); foo(pgdat); }}hjMsbah}(h]h ]h"]h$]h&]hhuh1j8hhhKhj,hhubjk)}(hhh](jp)}(h节点数据结构h]h节点数据结构}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1johj[hhhhhKubh)}(h节点结构 ``struct pglist_data`` 在 ``include/linux/mmzone.h`` 中声明。这里我们将简要描述这个结构体的字段:h](h 节点结构 }(hjlhhhNhNubj)}(h``struct pglist_data``h]hstruct pglist_data}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh 在 }(hjlhhhNhNubj)}(h``include/linux/mmzone.h``h]hinclude/linux/mmzone.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubhC 中声明。这里我们将简要描述这个结构体的字段:}(hjlhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj[hhubjk)}(hhh](jp)}(h 通用字段h]h 通用字段}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(h``node_zones`` 表示该节点的区域列表。并非所有区域都可能被填充,但这是 完整的列表。它被该节点的node_zonelists以及其它节点的 node_zonelists引用。h](j)}(h``node_zones``h]h node_zones}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 表示该节点的区域列表。并非所有区域都可能被填充,但这是 完整的列表。它被该节点的node_zonelists以及其它节点的 node_zonelists引用。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h``node_zonelists`` 表示所有节点中所有区域的列表。此列表定义了分配内存时首选的区域 顺序。``node_zonelists`` 在核心内存管理结构初始化期间, 由 ``mm/page_alloc.c`` 中的 ``build_zonelists()`` 函数设置。h](j)}(h``node_zonelists``h]hnode_zonelists}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhh 表示所有节点中所有区域的列表。此列表定义了分配内存时首选的区域 顺序。}(hjhhhNhNubj)}(h``node_zonelists``h]hnode_zonelists}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh3 在核心内存管理结构初始化期间, 由 }(hjhhhNhNubj)}(h``mm/page_alloc.c``h]hmm/page_alloc.c}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 中的 }(hjhhhNhNubj)}(h``build_zonelists()``h]hbuild_zonelists()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 函数设置。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h:``nr_zones`` 表示此节点中已填充区域的数量。h](j)}(h ``nr_zones``h]hnr_zones}(hj! hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. 表示此节点中已填充区域的数量。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h``node_mem_map`` 对于使用FLATMEM内存模型的UMA系统,0号节点的 ``node_mem_map`` 表示每个物理帧的struct pages数组。h](j)}(h``node_mem_map``h]h node_mem_map}(hj= hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9 ubh= 对于使用FLATMEM内存模型的UMA系统,0号节点的 }(hj9 hhhNhNubj)}(h``node_mem_map``h]h node_mem_map}(hjO hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9 ubh. 表示每个物理帧的struct pages数组。}(hj9 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h``node_page_ext`` 对于使用FLATMEM内存模型的UMA系统,0号节点的 ``node_page_ext`` 是struct pages的扩展数组。只有在构建时开启了 ``CONFIG_PAGE_EXTENSION`` 选项的内核中才可用。h](j)}(h``node_page_ext``h]h node_page_ext}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjg ubh= 对于使用FLATMEM内存模型的UMA系统,0号节点的 }(hjg hhhNhNubj)}(h``node_page_ext``h]h node_page_ext}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjg ubh> 是struct pages的扩展数组。只有在构建时开启了 }(hjg hhhNhNubj)}(h``CONFIG_PAGE_EXTENSION``h]hCONFIG_PAGE_EXTENSION}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjg ubh 选项的内核中才可用。}(hjg hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hF``node_start_pfn`` 表示此节点中起始页面帧的页面帧号。h](j)}(h``node_start_pfn``h]hnode_start_pfn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh4 表示此节点中起始页面帧的页面帧号。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hJ``node_present_pages`` 表示此节点中存在的物理页面的总数。h](j)}(h``node_present_pages``h]hnode_present_pages}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh4 表示此节点中存在的物理页面的总数。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hS``node_spanned_pages`` 表示包括空洞在内的物理页面范围的总大小。h](j)}(h``node_spanned_pages``h]hnode_spanned_pages}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh= 表示包括空洞在内的物理页面范围的总大小。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX|``node_size_lock`` 一个保护定义节点范围字段的锁。仅在开启了 ``CONFIG_MEMORY_HOTPLUG`` 或 ``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` 配置选项中的某一个时才定义。提 供了 ``pgdat_resize_lock()`` 和 ``pgdat_resize_unlock()`` 用来操作 ``node_size_lock``,而无需检查 ``CONFIG_MEMORY_HOTPLUG`` 或 ``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` 选项。h](j)}(h``node_size_lock``h]hnode_size_lock}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh> 一个保护定义节点范围字段的锁。仅在开启了 }(hj hhhNhNubj)}(h``CONFIG_MEMORY_HOTPLUG``h]hCONFIG_MEMORY_HOTPLUG}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 或 }(hj hhhNhNubj)}(h$``CONFIG_DEFERRED_STRUCT_PAGE_INIT``h]h CONFIG_DEFERRED_STRUCT_PAGE_INIT}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh6 配置选项中的某一个时才定义。提 供了 }(hj hhhNhNubj)}(h``pgdat_resize_lock()``h]hpgdat_resize_lock()}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 和 }(hj hhhNhNubj)}(h``pgdat_resize_unlock()``h]hpgdat_resize_unlock()}(hjG hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 用来操作 }(hj hhhNhNubj)}(h``node_size_lock``h]hnode_size_lock}(hjY hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh,而无需检查 }(hj hhhNhNubj)}(h``CONFIG_MEMORY_HOTPLUG``h]hCONFIG_MEMORY_HOTPLUG}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 或 }hj sbj)}(h$``CONFIG_DEFERRED_STRUCT_PAGE_INIT``h]h CONFIG_DEFERRED_STRUCT_PAGE_INIT}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 选项。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h6``node_id`` 节点的节点ID(NID),从0开始。h](j)}(h ``node_id``h]hnode_id}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh+ 节点的节点ID(NID),从0开始。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hh``totalreserve_pages`` 这是每个节点保留的页面,这些页面不可用于用户空间分配。h](j)}(h``totalreserve_pages``h]htotalreserve_pages}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhR 这是每个节点保留的页面,这些页面不可用于用户空间分配。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h``first_deferred_pfn`` 如果大型机器上的内存初始化被推迟,那么第一个PFN(页帧号)是需要初始化的。 在开启了 ``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` 选项时定义。h](j)}(h``first_deferred_pfn``h]hfirst_deferred_pfn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh{ 如果大型机器上的内存初始化被推迟,那么第一个PFN(页帧号)是需要初始化的。 在开启了 }(hj hhhNhNubj)}(h$``CONFIG_DEFERRED_STRUCT_PAGE_INIT``h]h CONFIG_DEFERRED_STRUCT_PAGE_INIT}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 选项时定义。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h``deferred_split_queue`` 每个节点的大页队列,这些大页的拆分被推迟了。仅在开启了 ``CONFIG_TRANSPARENT_HUGEPAGE`` 配置选项时定义。h](j)}(h``deferred_split_queue``h]hdeferred_split_queue}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhS 每个节点的大页队列,这些大页的拆分被推迟了。仅在开启了 }(hj hhhNhNubj)}(h``CONFIG_TRANSPARENT_HUGEPAGE``h]hCONFIG_TRANSPARENT_HUGEPAGE}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 配置选项时定义。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h``__lruvec`` 每个节点的lruvec持有LRU(最近最少使用)列表和相关参数。仅在禁用了内存 控制组(cgroups)时使用。它不应该直接访问,而应该使用 ``mem_cgroup_lruvec()`` 来查找lruvecs。h](j)}(h ``__lruvec``h]h__lruvec}(hj- hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj) ubh 每个节点的lruvec持有LRU(最近最少使用)列表和相关参数。仅在禁用了内存 控制组(cgroups)时使用。它不应该直接访问,而应该使用 }(hj) hhhNhNubj)}(h``mem_cgroup_lruvec()``h]hmem_cgroup_lruvec()}(hj? hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj) ubh 来查找lruvecs。}(hj) hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id4ah ]h"] 通用字段ah$]h&]uh1jjhj[hhhhhKubjk)}(hhh](jp)}(h 回收控制h]h 回收控制}(hjb hhhNhNubah}(h]h ]h"]h$]h&]uh1johj_ hhhhhMubh)}(h>另见内核文档 Documentation/mm/page_reclaim.rst 文件。h]h>另见内核文档 Documentation/mm/page_reclaim.rst 文件。}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(h5``kswapd`` 每个节点的kswapd内核线程实例。h](j)}(h ``kswapd``h]hkswapd}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ ubh+ 每个节点的kswapd内核线程实例。}(hj~ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj_ hhubh)}(ha``kswapd_wait``, ``pfmemalloc_wait``, ``reclaim_wait`` 同步内存回收任务的工作队列。h](j)}(h``kswapd_wait``h]h kswapd_wait}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh, }(hj hhhNhNubj)}(h``pfmemalloc_wait``h]hpfmemalloc_wait}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh, }hj sbj)}(h``reclaim_wait``h]h reclaim_wait}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh+ 同步内存回收任务的工作队列。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj_ hhubh)}(hN``nr_writeback_throttled`` 等待写回脏页时,被限制的任务数量。h](j)}(h``nr_writeback_throttled``h]hnr_writeback_throttled}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh4 等待写回脏页时,被限制的任务数量。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(h4``kswapd_order`` 控制kswapd尝试回收的order。h](j)}(h``kswapd_order``h]h kswapd_order}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh$ 控制kswapd尝试回收的order。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(hK``kswapd_highest_zoneidx`` kswapd线程可以回收的最高区域索引。h](j)}(h``kswapd_highest_zoneidx``h]hkswapd_highest_zoneidx}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh1 kswapd线程可以回收的最高区域索引。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(hD``kswapd_failures`` kswapd无法回收任何页面的运行次数。h](j)}(h``kswapd_failures``h]hkswapd_failures}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj. ubh1 kswapd无法回收任何页面的运行次数。}(hj. hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(h``min_unmapped_pages`` 无法回收的未映射文件支持的最小页面数量。由 ``vm.min_unmapped_ratio`` 系统控制台(sysctl)参数决定。在开启 ``CONFIG_NUMA`` 配置时定义。h](j)}(h``min_unmapped_pages``h]hmin_unmapped_pages}(hjN hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJ ubhA 无法回收的未映射文件支持的最小页面数量。由 }(hjJ hhhNhNubj)}(h``vm.min_unmapped_ratio``h]hvm.min_unmapped_ratio}(hj` hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJ ubh5 系统控制台(sysctl)参数决定。在开启 }(hjJ hhhNhNubj)}(h``CONFIG_NUMA``h]h CONFIG_NUMA}(hjr hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJ ubh 配置时定义。}(hjJ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(h``min_slab_pages`` 无法回收的SLAB页面的最少数量。由 ``vm.min_slab_ratio`` 系统控制台 (sysctl)参数决定。在开启 ``CONFIG_NUMA`` 时定义。h](j)}(h``min_slab_pages``h]hmin_slab_pages}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh0 无法回收的SLAB页面的最少数量。由 }(hj hhhNhNubj)}(h``vm.min_slab_ratio``h]hvm.min_slab_ratio}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh6 系统控制台 (sysctl)参数决定。在开启 }(hj hhhNhNubj)}(h``CONFIG_NUMA``h]h CONFIG_NUMA}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 时定义。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj_ hhubh)}(h+``flags`` 控制回收行为的标志位。h](j)}(h ``flags``h]hflags}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh" 控制回收行为的标志位。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM#hj_ hhubeh}(h]id5ah ]h"] 回收控制ah$]h&]uh1jjhj[hhhhhMubjk)}(hhh](jp)}(h内存压缩控制h]h内存压缩控制}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1johj hhhhhM'ubh)}(hA``kcompactd_max_order`` kcompactd应尝试实现的页面order。h](j)}(h``kcompactd_max_order``h]hkcompactd_max_order}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh* kcompactd应尝试实现的页面order。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM)hj hhubh)}(hK``kcompactd_highest_zoneidx`` kcompactd可以压缩的最高区域索引。h](j)}(h``kcompactd_highest_zoneidx``h]hkcompactd_highest_zoneidx}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. kcompactd可以压缩的最高区域索引。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM,hj hhubh)}(h=``kcompactd_wait`` 同步内存压缩任务的工作队列。h](j)}(h``kcompactd_wait``h]hkcompactd_wait}(hj; hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj7 ubh+ 同步内存压缩任务的工作队列。}(hj7 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM/hj hhubh)}(h;``kcompactd`` 每个节点的kcompactd内核线程实例。h](j)}(h ``kcompactd``h]h kcompactd}(hjW hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjS ubh. 每个节点的kcompactd内核线程实例。}(hjS hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM2hj hhubh)}(h``proactive_compact_trigger`` 决定是否使用主动压缩。由 ``vm.compaction_proactiveness`` 系统控 制台(sysctl)参数控制。h](j)}(h``proactive_compact_trigger``h]hproactive_compact_trigger}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjo ubh& 决定是否使用主动压缩。由 }(hjo hhhNhNubj)}(h``vm.compaction_proactiveness``h]hvm.compaction_proactiveness}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjo ubh, 系统控 制台(sysctl)参数控制。}(hjo hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM5hj hhubeh}(h]id6ah ]h"]内存压缩控制ah$]h&]uh1jjhj[hhhhhM'ubjk)}(hhh](jp)}(h 统计信息h]h 统计信息}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1johj hhhhhM:ubh)}(hG``per_cpu_nodestats`` 表示节点的Per-CPU虚拟内存统计信息。h](j)}(h``per_cpu_nodestats``h]hper_cpu_nodestats}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh2 表示节点的Per-CPU虚拟内存统计信息。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM<hj hhubh)}(h6``vm_stat`` 表示节点的虚拟内存统计数据。h](j)}(h ``vm_stat``h]hvm_stat}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh+ 表示节点的虚拟内存统计数据。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM?hj hhubj)}(h.. _zones_zh_CN:h]h}(h]h ]h"]h$]h&]j* zones-zh-cnuh1jhMMhj hhhhubeh}(h]id7ah ]h"] 统计信息ah$]h&]uh1jjhj[hhhhhM:ubeh}(h]id3ah ]h"]节点数据结构ah$]h&]uh1jjhj,hhhhhKubeh}(h](j+id2eh ]h"](节点 nodes_zh_cneh$]h&]uh1jjhjlhhhhhKexpect_referenced_by_name}jj sexpect_referenced_by_id}j+j subjk)}(hhh](jp)}(h区域h]h区域}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhMEubh admonition)}(h<本节内容不完整。请列出并描述相应的字段。h](jp)}(hStubh]hStub}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1johhhMGhj)ubh)}(hj+h]h<本节内容不完整。请列出并描述相应的字段。}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMIhj)ubeh}(h]h ]admonition-stubah"]h$]h&]uh1j'hjhhhhhNubj)}(h.. _pages_zh_CN:h]h}(h]h ]h"]h$]h&]j* pages-zh-cnuh1jhMVhjhhhhubeh}(h](j id8eh ]h"](区域 zones_zh_cneh$]h&]uh1jjhjlhhhhhMEj}j`j sj}j j subjk)}(hhh](jp)}(h页h]h页}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1johjehhhhhMNubj()}(h<本节内容不完整。请列出并描述相应的字段。h](jp)}(hStubh]hStub}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1johhhMPhjvubh)}(hjxh]h<本节内容不完整。请列出并描述相应的字段。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMRhjvubeh}(h]h ]admonition-stubah"]h$]h&]uh1j'hjehhhhhNubj)}(h.. _folios_zh_CN:h]h}(h]h ]h"]h$]h&]j* folios-zh-cnuh1jhM_hjehhhhubeh}(h](jYid9eh ]h"](页 pages_zh_cneh$]h&]uh1jjhjlhhhhhMNj}jjOsj}jYjOsubjk)}(hhh](jp)}(h页码h]h页码}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhMWubj()}(h<本节内容不完整。请列出并描述相应的字段。h](jp)}(hStubh]hStub}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johhhMYhjubh)}(hjh]h<本节内容不完整。请列出并描述相应的字段。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM[hjubeh}(h]h ]admonition-stubah"]h$]h&]uh1j'hjhhhhhNubj)}(h.. _initialization_zh_CN:h]h}(h]h ]h"]h$]h&]j*initialization-zh-cnuh1jhMhhjhhhhubeh}(h](jid10eh ]h"](页码 folios_zh_cneh$]h&]uh1jjhjlhhhhhMWj}jjsj}jjsubjk)}(hhh](jp)}(h 初始化h]h 初始化}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhM`ubj()}(h<本节内容不完整。请列出并描述相应的字段。h](jp)}(hStubh]hStub}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johhhMbhjubh)}(hjh]h<本节内容不完整。请列出并描述相应的字段。}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMdhjubeh}(h]h ]admonition-stubah"]h$]h&]uh1j'hjhhhhhNubeh}(h](jid11eh ]h"]( 初始化initialization_zh_cneh$]h&]uh1jjhjlhhhhhM`j}j<jsj}jjsubeh}(h]id1ah ]h"] 物理内存ah$]h&]uh1jjhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(joN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjlerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}(j+]j aj ]j ajY]jOaj]jaj]jaunameids}(jFjCjj+jj jjj\ jY j j j j j j j`j j_j\jjYjjjjjjj<jj;j8u nametypes}(jFjjjj\ j j j j`j_jjjjj<j;uh}(jCjlj+j,j j,jj[jY jj j_ j j j j j jj\jjYjejjejjjjjjj8ju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jzK sRparse_messages]transform_messages](hsystem_message)}(hhh]h)}(hhh]h1Hyperlink target "nodes-zh-cn" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehnjlineKuh1jubj)}(hhh]h)}(hhh]h1Hyperlink target "zones-zh-cn" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypejsourcehnjlineMMuh1jubj)}(hhh]h)}(hhh]h1Hyperlink target "pages-zh-cn" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypejsourcehnjlineMVuh1jubj)}(hhh]h)}(hhh]h2Hyperlink target "folios-zh-cn" is not referenced.}hj)sbah}(h]h ]h"]h$]h&]uh1hhj&ubah}(h]h ]h"]h$]h&]levelKtypejsourcehnjlineM_uh1jubj)}(hhh]h)}(hhh]h:Hyperlink target "initialization-zh-cn" is not referenced.}hjCsbah}(h]h ]h"]h$]h&]uh1hhj@ubah}(h]h ]h"]h$]h&]levelKtypejsourcehnjlineMhuh1jube transformerN include_log]7Documentation/translations/zh_CN/mm/physical_memory.rst(NNNNta decorationNhhub.