【Linux 内核 内存管理】物理内存组织结构

news/2024/11/19 19:40:31/

一、 UMA和NUMA两种模型
共享存储型多处理机有两种模型
一致内存访问(Uniform-Memory-Access,简称UMA)模型

非一致内存访问(Nonuniform-Memory-Access,简称NUMA)模型

UMA模型
物理存储器被所有处理器件均匀共享。所有处理机对所有存储字具有相同的存取时间,这就是为什么称它为均匀存储器存取的原因。每台处理机可以有私用高速缓存,外围设备也以一定形式共享。
在这里插入图片描述

NUMA模型
NUMA模式下,处理器被划分成多个”节点”(node), 每个节点被分配有的本地存储器空间。 所有节点中的处理器都可以访问全部的系统物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多。
在这里插入图片描述
Linux适用于各种不同的体系结构, 而不同体系结构在内存管理方面的差别很大. 因此linux内核需要用一种体系结构无关的方式来表示内存。
在 NUMA 非一致内存访问架构 中, 将 CPU 划分为多个节点 , 每个节点都有自己的 " 内存控制器 " 和 " 内存插槽 " , CPU 访问自己的节点上的 内存 很快 , 但是访问其它 CPU 的内存 很慢 ;
在UMA结构下, 则任务系统中只存在一个内存node, 这样对于UMA结构来说, 内核把内存当成只有一个内存node节点的伪NUMA。

注意:NUMA 内存节点分为两种情况

  • 根据 " 处理器与内存的距离 " 划分 " 内存节点 " ;
  • 在 不连续内存 的 NUMA 架构中 , 根据 " 物理地址是否连续 " 划分 " 内存节点 " , 每个 物理地址连续 的内存块 是一个 " 内存节点 " ;

二、内存管理系统 3 级结构

① 节点 Node ,
② 区域 Zone ,
③ 页 Page ,
Linux 内核中 , 使用 上述 3级结构 描述 和 管理 " 物理内存 " ;

2.1 内存节点 pglist_data 结构体
Linux 内核中 , 使用 pglist_data 结构体 描述 " 内存节点 " , 该结构体定义在 Linux 内核源码中的 linux-4.12\include\linux\mmzone.h#601 位置 ;
其中 :
node_zones 是 内存区域数组 ;

struct zone node_zones[MAX_NR_ZONES];

node_zonelists 是 备用区域列表 ;

struct zonelist node_zonelists[MAX_ZONELISTS];

nr_zones 是 该 " 内存节点 " 包含 多少个 " 内存区域 " ;

// 该 " 内存节点 " 包含 多少个 " 内存区域 "
int nr_zones;

CONFIG_FLAT_NODE_MEM_MAP 宏定义指的是 " 除 稀疏内存模型 之外 " 的情况 , 该情况下 声明 struct page *node_mem_map 页描述数组 ;
struct page_ext *node_page_ext 是 内存页的扩展属性 ;

#ifdef CONFIG_FLAT_NODE_MEM_MAP	/* means !SPARSEMEM */// 页描述数组struct page *node_mem_map;
#ifdef CONFIG_PAGE_EXTENSION// 内存页的扩展属性struct page_ext *node_page_ext;
#endif
#endif

node_start_pfn 是 该 " 内存节点 " 的 起始物理页 编号 ;
node_present_pages 是 物理页 的总数 ;
node_spanned_pages 是 物理页 的区间范围 总大小 , 该大小包括 " 内存空洞 " 大小 ;
node_id 是 节点标识符 ;

2.2 内存区域 zone 简介
" 内存节点 " 再向下划分 , 就是 " 内存区域 " zone ,
" 内存区域 " 在 Linux 内核中使用 struct zone 结构体类型进行描述 , zone 枚举定义在 Linux 内核源码的 linux-4.12\include\linux\mmzone.h#350 位置 ;

enum zone_type {
#ifdef CONFIG_ZONE_DMA//如果一些设备不能直接访问所有内存,需要使用DMA内存,例如ISA总线只能直接访问16MB以下的内存.不需要通过MMU管理,连续分配,具有更高的性能ZONE_DMA,
#endif
#ifdef CONFIG_ZONE_DMA32//标记了使用32位地址可寻址、适合DMA的内存域,显然只有64位系统上,才会有该内存域。ZONE_DMA32,
#endif//可以直接映射到内核段的普通内存域,这是所有体系机构上保证都会存在的唯一内存域,在IA-32系统上,该域可访问的最大内存不超过896MiB,超过该值的内存只能能通过高端内存寻址访问ZONE_HIGHMEM中的内存。ZONE_NORMAL,
#ifdef CONFIG_HIGHMEM//超出了内核段的物理内存。只有在可用物理内存多余可映射的内核内存时,才会访问该域,显然一般只有32位系统上才会有可能有该区域。通过kmap及kunmap将该域内存映射到内核虚拟地址空间。ZONE_HIGHMEM,
#endif
//伪内存区域,用来防止内存区域ZONE_MOVABLE,
#ifdef CONFIG_ZONE_DEVICE
//为了支持持久内存热拔插增加的内存区域,每个内存区域用一个zone结构体控制ZONE_DEVICE,
#endif__MAX_NR_ZONES};

ZONE的数据结构如下:

struct zone {unsigned long _watermark[NR_WMARK];unsigned long watermark_boost;unsigned long nr_reserved_highatomic;long lowmem_reserve[MAX_NR_ZONES];const char      *name;struct free_area    free_area[MAX_ORDER];unsigned long       flags;
}
  • 水位: 每个zone都有三个水位值
    WMARK_MIN: 最低水位,代表内存显然已经不够用了。
    WMARK_LOW:低水位,代表内存已经开始吃紧,需要启动回收页内核线性kswapped去回收内存
    WMARK_HIGH:高水位,代表内存还是足够的。
enum zone_watermarks {WMARK_MIN,WMARK_LOW,WMARK_HIGH,NR_WMARK
};
  • lowmem_reserve: 这个zone区域保留的内存,当系统内存出现不足的时候,系统就会使用这些保留的内存来做一些操作,比如使用保留的内存进程用来可以释放更多的内存
  • free_area:用于维护空闲的页,其中数组的下标对应页的order数。最大order目前是11,free_are的结构体。
struct free_area {struct list_head    free_list[MIGRATE_TYPES];unsigned long       nr_free;
};
  • free_list:用于将各个order的free page链接在一起
  • nr_free: 代表这个order中还有多个空闲page
    而每一个order中又根据迁移类型分成了几组。
enum migratetype {MIGRATE_UNMOVABLE,MIGRATE_MOVABLE,MIGRATE_RECLAIMABLE,
#ifdef CONFIG_CMAMIGRATE_CMA,
#endifMIGRATE_PCPTYPES, /* the number of types on the pcp lists */MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,
#ifdef CONFIG_MEMORY_ISOLATIONMIGRATE_ISOLATE,    /* can't allocate from here */
#endifMIGRATE_TYPES
};
MIGRATE_UNMOVABLE: 不可移动的页
MIGRATE_MOVABLE:可以移动的页,当出现内存碎片的时候,就可以移动此页,腾出更多连续的空间
MIGRATE_RECLAIMABLE:可以回收的页
MIGRATE_CMA:用于专门CMA申请的页
MIGRATE_PCPTYPES:per-cpu的使用的
MIGRATE_HIGHATOMIC:高阶原子分配
MIGRATE_ISOLATE:隔离,不能从此分配页

在这里插入图片描述
可以通过我当前的设备,查看page的信息cat /proc/pagetypeinfo
在这里插入图片描述
可以很清晰的看到各个order中不同类型,不同zone,page的剩余情况。当然也可以从cat /proc/buddyinfo看各个page的剩余情况。
当然了我们的zone,也可以通过cat /proc/zoneinfo去查看zone的详细信息的。

root:/ # cat /proc/zoneinfo
Node 0, zone   Normalpages free     126204min      1251low      9254high     9566spanned  1308544present  1180543managed  1136476protection: (0, 24576)nr_free_pages 126204nr_zone_inactive_anon 984nr_zone_active_anon 61238nr_zone_inactive_file 423539nr_zone_active_file 122889nr_zone_unevictable 987nr_zone_write_pending 288nr_mlock     987nr_page_table_pages 13969nr_kernel_stack 36784nr_bounce    0nr_zspages   0nr_free_cma  60532
Node 0, zone  Movablepages free     680267min      866low      6404high     6620spanned  786432present  786432managed  786432protection: (0, 0)nr_free_pages 680267nr_zone_inactive_anon 0nr_zone_active_anon 104777nr_zone_inactive_file 0nr_zone_active_file 0nr_zone_unevictable 121nr_zone_write_pending 0nr_mlock     121nr_page_table_pages 0nr_kernel_stack 0nr_bounce    0nr_zspages   0nr_free_cma  0

2.3 物理页
每个物理页对应一个page结构体,称为页描述符。内存节点的pglist_data实例的成员node_mem_map指向该内存节点包含的所有物理页的页描述符组成的数组。
页是内存管理中的最小单位,页面中的内存其物理地址是连续的,每个物理页由struct page描述。为了节省内存,struct page是一个联合体。
页,又称为页帧,在内核当中,内存管理单元MMU(负责虚拟地址和物理地址转换的硬件)是把物理页page作为内存管理的基本单位。体系结构不同,支持的页大小也相同。
32位体系结构支持4kb的页;64位体系结构支持8kb的页;MIPS64架构体系支持16kb的页。
Linux内核源码分析:include/linux/mm_types.h

struct page {unsigned long flags;//原子标志,有些情况下会异步更新union {struct {	/* Page cache and anonymous pages */struct list_head lru;//如果最低位位0,则指向inode address_space 或为NULL//如果页映射为匿名地址,最低位置位,而且指针指向anon_vma对象struct address_space *mapping;pgoff_t index;		/* Our offset within mapping. *///由映射私有,不透明数据;//如果设置了PagePrivate,通常用于buffer_heads,//如果设置了PageSwapCache,则用于swp_entry_t//如果设置了PageBuddy 则用于伙伴系统中的阶unsigned long private;};struct {	/* slab, slob and slub */union {struct list_head slab_list;struct {	/* Partial pages */struct page *next;
#ifdef CONFIG_64BITint pages;	/* Nr of pages left */int pobjects;	/* Approximate count */
#elseshort int pages;short int pobjects;
#endif};};struct kmem_cache *slab_cache; /* not slob *//* Double-word boundary */void *freelist;		/* first free object */union {void *s_mem;	/* slab: first object */unsigned long counters;		/* SLUB */struct {			/* SLUB */unsigned inuse:16;unsigned objects:15;unsigned frozen:1;};};};
...
}

http://www.ppmy.cn/news/5543.html

相关文章

揭秘百度智能测试在测试定位领域实践

作者 | intelligents 前几篇,分别介绍了测试活动测试输入、测试执行、测试分析、测试定位和测试评估五个步骤中测试输入、执行、分析、评估的智能化研究和实践,本章节重点介绍测试定位环节的智能化实践。 测试定位的主要作用是在构建失败或问题发生后&…

LabVIEW在两台计算机之间传输数据

LabVIEW在两台计算机之间传输数据 有几种网络协议可用于完成此任务。使用正确的网络协议白皮书将完成为应用选择正确协议的任务。它涵盖了控制和监视应用中最常用的通信模型,并根据配置、性能、易用性等推荐最适合每种情况的网络协议。 参考的白皮书重点介绍了三种…

LLVM中矩阵Matrix的实现分析

1 背景说明 Clang提供了C/C语言对矩阵的扩展支持,以方便用户使用可变大小的二维数据类型来实现计算,目前该特性还是实验版,设计和实现都在变化中。LLVM目前设计为支持小型列矩阵(column major),其对矩阵的…

Python中的基本数据类型

文章目录前言一、字符串类型字符串表示方法二、数字类型1. 整数2.浮点数3.复数三、布尔类型总结前言 我们一般在电脑中存储的数据有多种数据类型。比如下图这张员工工资表: 表中员工姓名可以用字符串类型存储(比如"李世民"、“侯君集”&#…

【经典问题:HanoiTower(汉诺塔)】

🎁HanoiTower🎅HanoiTower问题描述🎅🎅模拟推导🎅🎅🎅问题的两种形式🎄求解移动总次数🎄🎄打印详细的移动过程🎅HanoiTower问题描述 汉诺塔问题&a…

路由选择协议(计算机网络)

目录 理想的路由算法 关于最佳路由 从路由算法的自适应性考虑 互联网分层路由 分层路由和自治系统 边界网关协议 BGP 理想的路由算法 算法必须是正确的和完整的 算法在计算上应简单 算法应能适应通信量和网络拓扑的变化,这就是说,要有自适应性 算法…

圣诞节怎么能缺少圣诞树呢?Python+HTML打造专属于你的圣诞树

前言: 美酒一杯让人醉,温馨陪伴浪漫随;雪花片片惹人爱,烦恼忧伤全不见;字里行间藏真情,文短情深送心愿:圣诞佳节快来到,祝大家永远开心幸福! Hello大家好,我是Dream。 圣诞节马上到了,一些朋友问…

【键盘的自动弹出和自动隐藏 Objective-C语言】

一、键盘的自动隐藏 1.点完“计算”按钮之后,键盘怎么才能自动隐藏 2.首先,键盘弹回去,这里有一个概念,叫做“第一响应者”,first responder 什么叫做第一响应者呢 当我去点击第一个文本框的时候 是不是由这个文本框叫出这个键盘啊 当我去点击第二个文本框的时候 是…