0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

物理内存模型的演变

jf_0tjVfeJz 来源:嵌入式ARM和Linux 2024-02-25 10:35 次阅读

内存管理概述中,主要是以Linux v2.6.11为例进行分析的,但是计算技术在不断发展,新的存储架构、新的指令集架构、新的SoC架构等都对物理内存模型的抽象提出了更高要求。为此,必须抽象一种完全独立于硬件架构的物理内存模型。

1 NUMA和UMA

第一个要解决的问题就是非一致性内存访问(NUMA)。对于多核和多内存卡插槽的机器,内存位于不同的分组中,那么与处理器的距离不同,就会产生访问时间的差异。比如,可以将一组内存更靠近CPU,另一组内存更靠近外设,作为访问外设的DMA内存。

这样的每个分组称为一个节点(node)。不管是NUMA架构,还是UMA架构,Linux提供了一个统一的数据结构struct pglist_data表示节点信息。该列表中是类型为pg_data_t的数据结构,描述一个具体的节点,该数据结构可以通过NODE_DATA(nid)引用,这儿nid表示节点的ID。

对于NUMA架构,node数据结构是由特定于架构的代码在boot阶段分配的。通常,这些数据结构分配的就是本地的内存组(也就是离它们近的内存)。对于UMA体系结构,只使用一个名为cong_page_data的静态pg_data_t结构。节点将在下一节讨论。

2 内存分区(memory zone)

节点内的物理内存被划分为一个或多个区,这样的区称为Zone。这些内存分区的划分通常由硬件架构访问物理内存的限制决定。ZONE在内核中的数据类型是zone_t,结构是zone。zone的分类类型如下所示:

ZONE_DMA和ZONE_DMA32

当外设无法DMA访问所有可寻址内存(ZONE_NORMAL)时,使用ZONE_DMA和ZONE_DMA32。ZONE_DMA32用于覆盖整个32位地址空间的架构上。ZONE_DMA留给具有较小DMA寻址限制的区域。这种区别很重要,因为定义ZONE_DMA32时假定使用32位DMA掩码。某些64位平台可能需要2个区域,因为它们支持具有不同DMA寻址限制的外设。虽然近些年提供了更好、更强大的接口分配DMA内存(使用通用设备的动态DMA映射),但ZONE_DMA和ZONE_DMA32仍然表示对其访问方式受限制的内存。根据架构不同,可以使用CONFIG_ZONE_DMA和CONFIG_ZONE_DMA32配置选项,在构建内核时,禁用这些内存区域。

ZONE_NORMAL

普通内存,内核一直可以访问的内存区。如果DMA设备支持向所有可寻址内存的传输,则可以对这些内存页执行DMA操作。ZONE_NORMAL总是使能。

ZONE_HIGHMEM

是内核页表中永久映射未覆盖的物理内存部分。这个区域中的内存只能由内核使用临时映射访问。该区域仅在某些32位体系结构上可用,并通过CONFIG_HIGHMEM启用。

ZONE_MOVABLE

与ZONE_NORMAL类似。不同之处是ZONE_MOVABLE区的内存页是可移动的。也就是说,在这些内存页的虚拟地址不改变的情况下,他们的内容可以在不同的物理内存页之间搬运。ZONE_MOVABLE通常在内存热插拔期间进行填充,但也可以在boot阶段,使用kernelcore、movablecore和movable_node命令行参数之一进行填充。具体可以参考内存页迁移和热插拔

ZONE_DEVICE

表示驻留在PMEM和GPU等设备上的内存。它和内存ZONE类型有着不同,它的存在是为了设备驱动程序的物理内存范围提供page和内存映射服务。ZONE_DEVICE可以通过配置选项CONFIG_ZONE_DEVICE使能。设备内存热插拔支持在mem_map中建立PMEM或其它设备驱动程序发现的内存区域。这允许pfn_to_page()查找“设备物理”地址,这是在O_DIRECT操作中使用DAX映射所需要的。

需要注意的是,许多内核操作只能使用ZONE_NORMAL进行,因此它是性能最关键的ZONE区。

节点和ZONE之间的关系由固件报告的物理内存映射、内存寻址的体系结构约束和内核命令行中的某些参数决定。

例如,对于具有2GB内存的x86 UMA架构内核,整个内存将位于节点0上,分为3个区域:“ZONE_DMA”、“ZONE_NORMAL”和“ZONE_HIGHMEM”:

02G
+-------------------------------------------------------------+
|node0|
+-------------------------------------------------------------+

016M896M2G
+----------+-----------------------+--------------------------+
|ZONE_DMA|ZONE_NORMAL|ZONE_HIGHMEM|
+----------+-----------------------+--------------------------+

ARM64机器上禁用ZONE_DMA并启用ZONE_DMA32的同时,使用movablecore = 80%参数启动内核时,在两个节点之间平均分配16G内存,则节点0上将有ZONE_DMA32,ZONE_NORMAL和ZONE_MOVABLE,节点1上将有ZONE_NORMAL和ZONE_MOVABLE:

1G9G17G
+--------------------------------++--------------------------+
|node0||node1|
+--------------------------------++--------------------------+

1G4G4200M9G9320M17G
+---------+----------+-----------++------------+-------------+
|DMA32|NORMAL|MOVABLE||NORMAL|MOVABLE|
+---------+----------+-----------++------------+-------------+

内存组也可以交替分配给节点。在下面的示例中,x86机器具有16G的内存,分为4组,偶数组属于节点0,奇数组属于节点1:

04G8G12G16G
+-------------++-------------++-------------++-------------+
|node0||node1||node0||node1|
+-------------++-------------++-------------++-------------+

016M4G
+-----+-------++-------------++-------------++-------------+
|DMA|DMA32||NORMAL||NORMAL||NORMAL|
+-----+-------++-------------++-------------++-------------+

在这种情况下,节点0将横跨0→12G,节点1将横跨4→16G。

3 节点

正如我们所提到的,内存中的每个节点都由pg_data_t描述,pg_data_t是结构体pglist_data的类型定义。在分配页面时,默认情况下Linux使用节点本地分配策略,从离运行CPU最近的节点分配内存。由于进程倾向于在同一个CPU上运行,因此很可能会使用当前节点的内存。分配策略可以由用户控制,详见NUMA内存策略。

大多数NUMA体系结构维护一个指向node结构的指针数组。实际的结构是在boot过程的早期分配的,当特定于体系结构的代码解析固件报告的物理内存映射时。节点初始化的大部分在boot过程中稍晚的时候通过free_area_init()函数进行,稍后将在初始化一节中描述。

除了node结构,内核还维护一个名为node_states的nodemask_t位掩码数组。这个数组中的每个位掩码代表一组具有特定属性的节点,这些属性由enum node_states定义:

N_POSSIBLE

节点可能在某个时间点在线。

N_ONLINE

节点在线。

N_NORMAL_MEMORY

节点具有常规内存。

N_HIGH_MEMORY

节点具有常规内存或高端内存。当CONFIG_HIGHMEM被禁用时,别名为N_NORMAL_MEMORY。

N_MEMORY

节点具有内存(常规、高、可移动).

N_CPU

节点内CPU数量。

对于具有上述属性的每个节点,将设置与node_states[]位掩码中节点ID对应的位。

例如,节点2,具有常规内存和CPU,位2将在下面设置:

node_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]

关于nodemask的各种操作,请参考include/linux/nodemask.h。

有了节点之后,LRU列表、页回收机制、交换区(kswapd)等等都需要在NONE分区之上添加处理。细节在此不再详述。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • soc
    soc
    +关注

    关注

    38

    文章

    3746

    浏览量

    215694
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206738
  • 内存
    +关注

    关注

    8

    文章

    2767

    浏览量

    72771
  • 模型
    +关注

    关注

    1

    文章

    2704

    浏览量

    47689

原文标题:Linux内核8.9-内存管理进阶之物理内存模型的演变

文章出处:【微信号:嵌入式ARM和Linux,微信公众号:嵌入式ARM和Linux】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux的内存管理是什么,Linux的内存管理详解

    。 一、物理内存模型   ​   物理内存模型主要分为两种:UMA(Uniform Memory
    的头像 发表于 05-11 17:54 5288次阅读
    Linux的<b class='flag-5'>内存</b>管理是什么,Linux的<b class='flag-5'>内存</b>管理详解

    Linux内核的物理内存组织结构详解

    Linux中内存管理子系统使用 节点(node)、区域(zone)和页(page) 三级结构描述物理内存
    发表于 08-21 15:35 246次阅读
    Linux内核的<b class='flag-5'>物理</b><b class='flag-5'>内存</b>组织结构详解

    用labview模拟物理模型

    课程推荐:http://z.elecfans.com/258.html?elecfans_trackid=bbs_toptxtlabview是很神奇的,可以模拟物理模型,挺好玩的
    发表于 05-13 22:55

    如何使用Simscape Multibody的物理建模模块来建立倒立摆模型

    Multibody的物理建模模块来建立倒立摆模型。Simscape库中的块代表实际的物理组件;因此,可以构建复杂的多体动力学模型,而无需通过物理
    发表于 07-07 06:16

    物理内存和虚拟内存之间的转换

    内存操作:涉及到了物理内存和虚拟内存之间的转换,需要用到两个函数: ioremap 和 iounmap。ioremap :函 数 用 于 获 取 指 定 物 理 地 址 空 间 对 应
    发表于 12-17 06:48

    Linux虚拟内存物理内存的深刻分析

    进程这种情况,浪费内存!第二层理解每个进程的4G内存空间只是虚拟内存空间,每次访问内存空间的某个地址,都需要把地址翻译为实际物理
    发表于 05-31 08:00

    UMTS的物理结构模型

    UMTS的物理结构模型
    发表于 09-18 15:13 1012次阅读

    物理内存使用率高的原因及解决办法

    主要讲解的就是物理内存使用率高的原因以及他的解决办法。导致物理内存使用率高有几种可能,而最常见的则有两种:一是安装不好的程序,内存被占用太多
    发表于 05-03 17:14 9066次阅读
    <b class='flag-5'>物理</b><b class='flag-5'>内存</b>使用率高的原因及解决办法

    NetWare内存模型与NetWare组网的介绍

    NetWare内存模型 N e t Ware 4.x只可以使用物理内存, N e t Ware 5.0可以同时使用物理
    发表于 11-23 17:51 3次下载

    如何避免Linux的物理内存碎片化

    Linux buddyy系统是linux kernel比较稳定的一个模块,但是并不是说它没有缺陷,Linux内存管理系统自诞生之日,就一直存在物理内存碎片化的问题:在系统启动并且运行很长一段时间
    的头像 发表于 05-01 16:43 5243次阅读
    如何避免Linux的<b class='flag-5'>物理</b><b class='flag-5'>内存</b>碎片化

    浅析计算机中物理内存模型

    个人感觉学这部分的知识应该首先在脑海中抽象出存储体系,因为无论磁盘,物理内存还是虚拟内存都是互相有联系的,抽象出模型有助于我们的理解和记忆。接着需要哪部分知识或再次深入哪部分知识,从体
    的头像 发表于 08-28 16:29 4187次阅读

    了解并学习Linux内存模型

    在linux内核中支持3中内存模型,分别是flat memory model,Discontiguous memory model和sparse memory model。所谓memory
    发表于 05-12 09:44 586次阅读
    了解并学习Linux<b class='flag-5'>内存</b><b class='flag-5'>模型</b>

    电脑物理内存过高的处理技巧

    电脑物理内存过高的处理技巧。很多时候,我们的一些电脑管家或者电脑助手都总会显示内存过大,需要我们及时清理。其实这一种提示中的内存过大,不是指我们的电脑中的
    发表于 06-19 10:26 2741次阅读
    电脑<b class='flag-5'>物理</b><b class='flag-5'>内存</b>过高的处理技巧

    CUDA 6中的统一内存模型

    NVIDIA在CUDA 6中引入了统一内存模型 ( Unified Memory ),这是CUDA历史上最重要的编程模型改进之一。在当今典型的PC或群集节点中,CPU和GPU的内存
    的头像 发表于 07-02 14:08 2435次阅读

    内存是怎么映射到物理地址空间的?内存是连续分布的吗?

    如果我们将两个4G内存插入内存插槽,得到的内存地址空间是0到8G吗?是不是0到4G是第一根内存,4到8G是第二根内存呢?实际情况相差甚远,
    的头像 发表于 06-30 15:59 2030次阅读
    <b class='flag-5'>内存</b>是怎么映射到<b class='flag-5'>物理</b>地址空间的?<b class='flag-5'>内存</b>是连续分布的吗?