深入理解Linux内核——内存管理

时间:2022-01-14 15:47:29
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理

1:页框的大小:4KB,4MB(如果PAE被激活,则为2MB)。 2:页描述符:     1)内核必须记录每个页框当前的状态。     2)内核必须能够区分哪些页框包含的是属于进程的页,而那些页框包含的是内核代码或者内核数据。
    3)空闲页框:动态内存中不包含有用数据。
          不空闲页框:包含用户态进程的数据,某个软件高速缓存的数据,动态分配的内核数据结构,设备驱动程序缓冲的数据,内核模块的代码。
    4)内核的状态信息保存在一个类型为page的页描述符中。所有的页描述符都存在mem_map数组中。每个描述符的长度为32字节。     5)virt_to_page(addr)宏产生线性地址addr对应的页描述符地址。
    6)pfn_to_page(pfn)宏产生与页框号pfn对应的页描述符地址。
深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
两个字段的详解: 深入理解Linux内核——内存管理
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
3:非一致性内存访问(Non-Uniform Memory Access,NUMA)     1)系统的物理内存被划分成几个节点(node)。每个节点中的物理内存又可以分为几个管理区(Zone)。每个节点都有一个类型为pg_data_t的描述符所有的节点的描述符存放在一个单向链表中,它的第一个元素由pgdat_list变量指向。
深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
4内存管理区     1)物理内存的3个管理区
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
        深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
注:1)每个页描述符都有到内存节点和到节点内管理区(包括相应页框)的链接。         2)这些链接被编码成索引存放在flags字段的高位。
        3)page_zone()函数接收一个页描述符的地址作为他的参数,它读取页描述符中的flags字段的最高位,然后通过查看zone_table数组来确定相应管理区描述符的地址。
        4)在启动时用所有内存节点的所有管理区描述符的地址初始化这个数组。
5保留的页框池     1)当请求内存时,一些内核控制路径不能被阻塞,即当在处理中断或在执行临界区内的代码时。
    2)一条内核控制路径应当产生原子内存分配请求(使用GFP_ATOMIC标志)
    3)内核为原子内存分配请求保留了一个页框池,只有在内存不足时使用。
    4)保留内存的数量(以KB为单位)存放在min_free_kbytes变量中。
    5)它的初始值在内核初始化时设置,并取决于直接映射到内核线性地址空间第4个GB的物理内存的数量。即取决于包含在ZONE_DMA和ZONE_NORMAL内存管理区内的页框数:
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
6:分区页框分配器 被称作分区页框分配器(zoned page frame allocator)的内核子系统,处理对连续页框组的内存分配请求。 深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
注:1)管理区分配器部分接受动态内存分配与释放的请求。在请求分配的情况下,该部分搜索一个能满足所请求的一组连续页框内存的管理区。        2)在每个管理区内,页框被名为“伙伴系统”。 7:请求和释放页框 可以用稍有差别的函数和宏请求页框。一般情况下,它们会返回第一个分配页的线性地址,或者如果分配失败,则返回NULL.
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
注:1)_ _GFP_DMA和_ _GFP_HIGHMEM标志被称作管理区修饰符,他们标示寻找空闲页框时内核所搜索的管理区。         2)conting_page_data节点描述符的node——zonelists字段是一个管理区描述符链表的数组,它代表后备管理区:对管理区修饰符的每一个设置,相应的链表包含的内存管理区能在原来的管理区缺少页框的情况下满足内存分配的请求。
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理

深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
8:高端内存页框的内核映射 深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
   永久内核映射)    永久内核映射允许内核建立高端页框到内核地址空间的长期映射。它们使用主内核页表中一个专门的页表,其地址放在pkmap_page_table变量中。页表中的表项数由LAST_PKMAP宏产生。 深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
临时内核映射 1)每个CPU都有它自己的包含13个窗口的集合,它们用enum km_type数据结构表示。该数据结构中定义的每个符号,如KM_BOUNCE_READ,KM_USER0或KM_PTE0,标识了窗口的线性地址。 2)窗口必须确保同一窗口永不会被两个不同的控制路径同时使用。 3)km_type结构中的每个符号只能由一种内核成分使用,并以该成分命名。 4)最后一个符号KM_TYPE_NR本身不表示一个线性地址,但由每个CPU用来产生不同的可用窗口数。 深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
伙伴系统算法
    1)外碎片:频繁的请求和释放不同大小的一组连续页框,导致在已经分配页框的块内分散了许多小块的空闲页框。     2)避免外碎片的方法:
          a:利用分页单元把一组非连续的空闲页框映射到连续的现性地址空间                注:利用非连续内存的分配,,一来用来映射非连续内存线性地址空间有限,二来每次映射都要改写内核的页表,进而就要刷新TLB,这使得分配的速度大打折扣,这对于要频繁申请内存的内核显然是无法忍受的           b:开发一种适当的技术来记录现存的空闲连续页框块的情况,以尽量避免为满足对小块的请求而分割大的空闲块。     TLB           a:TLB(Translation Lookaside Buffer)传输后备缓冲器是一个内存管理单元用于改进虚拟地址到物理地址转换速度的缓存。

   b:TLB是一个小的,虚拟寻址的缓存,其中每一行都保存着一个由单个PTE组成的块。如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据。

   c:TLB:Translation lookaside buffer,即旁路转换缓冲,或称为页表缓冲;里面存放的是一些页表文件(虚拟地址到物理地址的转换表)。

又称为快表技术。由于"页表"存储在主存储器中,查询页表所付出的代价很大,由此产生了TLB。

X86保护模式下的寻址方式:段式逻辑地址-〉线性地址-〉页式地址;

页式地址=页面起始地址+页内偏移地址;

对应于虚拟地址:叫page(页面);对应于物理地址:叫frame(页框);

X86体系的系统内存里存放了两级页表,第一级页表称为页目录,第二级称为页表

TLB和CPU里的一级、二级缓存之间不存在本质的区别,只不过前者缓存页表数据,而后两个缓存实际数据。

折叠内部组成

1:TLB在X86体系的CPU里的实际应用最早是从Intel的486CPU开始的,在X86体系的CPU里边,一般都设有如下4组TLB:

第一组:缓存一般页表(4K字节页面)的指令页表缓存(Instruction-TLB);

第二组:缓存一般页表(4K字节页面)的数据页表缓存(Data-TLB);

第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存(Instruction-TLB);

第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存(Data-TLB);

2:TLB命中和TLB失败

如果TLB中正好存放着所需的页表,则称为TLB命中(TLB Hit);如果TLB中没有所需的页表,则称为TLB失败(TLB Miss)。

3: TLB条目数 即TLB里面可以存储的表项数目,一般也叫entry数。

4:TLB的联合方式

1〉全相联方式:Athlon XP

2〉组相联方式:P4

当CPU执行机构收到应用程序发来的虚拟地址后,首先到TLB中查找相应的页表数据,如果TLB中正好存放着所需的页表,则称为TLB命中(TLB Hit),接下来CPU再依次看TLB中页表所对应的物理内存地址中的数据是不是已经在一级、二级缓存里了,若没有则到内存中取相应地址所存放的数据。既然说TLB是内存里存放的页表的缓存,那么它里边存放的数据实际上和内存页表区的数据是一致的,在内存的页表区里,每一条记录虚拟页面和物理页框对应关系的记录称之为一个页表条目(Entry),同样地,在TLB里边也缓存了同样大小的页表条目(Entry)。

内存试图把大小为b的一对空闲伙伴块合并为一个大小为2b的单独块。满足以下条件的两个快称为伙伴:

两个块具有相同的大小,记作b

他们的物理地址是连续的。

第一块的第一个页框的物理地址是2xbx2^12的倍数。

数据结构
    1)有三种伙伴系统,第一种适合处理ISA DMA的页框,第二种处理''常规"页框第三种处理高端内存页框。    2)深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理深入理解Linux内核——内存管理
分配块释放快每CPU页框高速缓存1)这里为每个内存管理区和每个cpu提供了两个高速缓存:热高速缓存(存放的页框中所包含的内容很有可能就在CPU硬件高速缓存中);冷高速缓存。
e


1:页框的大小:4KB,4MB(如果PAE被激活,则为2MB)。2:页描述符:    1)内核必须记录每个页框当前的状态。    2)内核必须能够区分哪些页框包含的是属于进程的页,而那些页框包含的是内核代码或者内核数据。
    3)空闲页框:动态内存中不包含有用数据。
          不空闲页框:包含用户态进程的数据,某个软件高速缓存的数据,动态分配的内核数据结构,设备驱动程序缓冲的数据,内核模块的代码。
    4)内核的状态信息保存在一个类型为page的页描述符中。所有的页描述符都存在mem_map数组中。每个描述符的长度为32字节。    5)virt_to_page(addr)宏产生线性地址addr对应的页描述符地址。
    6)pfn_to_page(pfn)宏产生与页框号pfn对应的页描述符地址。
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
两个字段的详解:深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
3:非一致性内存访问(Non-Uniform Memory Access,NUMA)    1)系统的物理内存被划分成几个节点(node)。每个节点中的物理内存又可以分为几个管理区(Zone)。每个节点都有一个类型为pg_data_t的描述符所有的节点的描述符存放在一个单向链表中,它的第一个元素由pgdat_list变量指向。
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
4内存管理区    1)物理内存的3个管理区
        深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
注:1)每个页描述符都有到内存节点和到节点内管理区(包括相应页框)的链接。        2)这些链接被编码成索引存放在flags字段的高位。
        3)page_zone()函数接收一个页描述符的地址作为他的参数,它读取页描述符中的flags字段的最高位,然后通过查看zone_table数组来确定相应管理区描述符的地址。
        4)在启动时用所有内存节点的所有管理区描述符的地址初始化这个数组。
5保留的页框池    1)当请求内存时,一些内核控制路径不能被阻塞,即当在处理中断或在执行临界区内的代码时。
    2)一条内核控制路径应当产生原子内存分配请求(使用GFP_ATOMIC标志)
    3)内核为原子内存分配请求保留了一个页框池,只有在内存不足时使用。
    4)保留内存的数量(以KB为单位)存放在min_free_kbytes变量中。
    5)它的初始值在内核初始化时设置,并取决于直接映射到内核线性地址空间第4个GB的物理内存的数量。即取决于包含在ZONE_DMA和ZONE_NORMAL内存管理区内的页框数:
深入理解Linux内核——内存管理
6:分区页框分配器被称作分区页框分配器(zoned page frame allocator)的内核子系统,处理对连续页框组的内存分配请求。深入理解Linux内核——内存管理
注:1)管理区分配器部分接受动态内存分配与释放的请求。在请求分配的情况下,该部分搜索一个能满足所请求的一组连续页框内存的管理区。       2)在每个管理区内,页框被名为“伙伴系统”。7:请求和释放页框可以用稍有差别的函数和宏请求页框。一般情况下,它们会返回第一个分配页的线性地址,或者如果分配失败,则返回NULL.
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
注:1)_ _GFP_DMA和_ _GFP_HIGHMEM标志被称作管理区修饰符,他们标示寻找空闲页框时内核所搜索的管理区。        2)conting_page_data节点描述符的node——zonelists字段是一个管理区描述符链表的数组,它代表后备管理区:对管理区修饰符的每一个设置,相应的链表包含的内存管理区能在原来的管理区缺少页框的情况下满足内存分配的请求。
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
8:高端内存页框的内核映射深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
   永久内核映射)   永久内核映射允许内核建立高端页框到内核地址空间的长期映射。它们使用主内核页表中一个专门的页表,其地址放在pkmap_page_table变量中。页表中的表项数由LAST_PKMAP宏产生。深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
临时内核映射1)每个CPU都有它自己的包含13个窗口的集合,它们用enum km_type数据结构表示。该数据结构中定义的每个符号,如KM_BOUNCE_READ,KM_USER0或KM_PTE0,标识了窗口的线性地址。2)窗口必须确保同一窗口永不会被两个不同的控制路径同时使用。3)km_type结构中的每个符号只能由一种内核成分使用,并以该成分命名。4)最后一个符号KM_TYPE_NR本身不表示一个线性地址,但由每个CPU用来产生不同的可用窗口数。深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
深入理解Linux内核——内存管理
伙伴系统算法
    1)外碎片:频繁的请求和释放不同大小的一组连续页框,导致在已经分配页框的块内分散了许多小块的空闲页框。    2)避免外碎片的方法:
          a:利用分页单元把一组非连续的空闲页框映射到连续的现性地址空间               注:利用非连续内存的分配,,一来用来映射非连续内存线性地址空间有限,二来每次映射都要改写内核的页表,进而就要刷新TLB,这使得分配的速度大打折扣,这对于要频繁申请内存的内核显然是无法忍受的          b:开发一种适当的技术来记录现存的空闲连续页框块的情况,以尽量避免为满足对小块的请求而分割大的空闲块。    TLB          a:TLB(Translation Lookaside Buffer)传输后备缓冲器是一个内存管理单元用于改进虚拟地址到物理地址转换速度的缓存。

   b:TLB是一个小的,虚拟寻址的缓存,其中每一行都保存着一个由单个PTE组成的块。如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据。

   c:TLB:Translation lookaside buffer,即旁路转换缓冲,或称为页表缓冲;里面存放的是一些页表文件(虚拟地址到物理地址的转换表)。

又称为快表技术。由于"页表"存储在主存储器中,查询页表所付出的代价很大,由此产生了TLB。

X86保护模式下的寻址方式:段式逻辑地址-〉线性地址-〉页式地址;

页式地址=页面起始地址+页内偏移地址;

对应于虚拟地址:叫page(页面);对应于物理地址:叫frame(页框);

X86体系的系统内存里存放了两级页表,第一级页表称为页目录,第二级称为页表

TLB和CPU里的一级、二级缓存之间不存在本质的区别,只不过前者缓存页表数据,而后两个缓存实际数据。

折叠内部组成

1:TLB在X86体系的CPU里的实际应用最早是从Intel的486CPU开始的,在X86体系的CPU里边,一般都设有如下4组TLB:

第一组:缓存一般页表(4K字节页面)的指令页表缓存(Instruction-TLB);

第二组:缓存一般页表(4K字节页面)的数据页表缓存(Data-TLB);

第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存(Instruction-TLB);

第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存(Data-TLB);

2:TLB命中和TLB失败

如果TLB中正好存放着所需的页表,则称为TLB命中(TLB Hit);如果TLB中没有所需的页表,则称为TLB失败(TLB Miss)。

3: TLB条目数 即TLB里面可以存储的表项数目,一般也叫entry数。

4:TLB的联合方式

1〉全相联方式:Athlon XP

2〉组相联方式:P4

当CPU执行机构收到应用程序发来的虚拟地址后,首先到TLB中查找相应的页表数据,如果TLB中正好存放着所需的页表,则称为TLB命中(TLB Hit),接下来CPU再依次看TLB中页表所对应的物理内存地址中的数据是不是已经在一级、二级缓存里了,若没有则到内存中取相应地址所存放的数据。既然说TLB是内存里存放的页表的缓存,那么它里边存放的数据实际上和内存页表区的数据是一致的,在内存的页表区里,每一条记录虚拟页面和物理页框对应关系的记录称之为一个页表条目(Entry),同样地,在TLB里边也缓存了同样大小的页表条目(Entry)。

内存试图把大小为b的一对空闲伙伴块合并为一个大小为2b的单独块。满足以下条件的两个快称为伙伴:

两个块具有相同的大小,记作b

他们的物理地址是连续的。

第一块的第一个页框的物理地址是2xbx2^12的倍数。

数据结构
    1)有三种伙伴系统,第一种适合处理ISA DMA的页框,第二种处理''常规"页框第三种处理高端内存页框。    2)深入理解Linux内核——内存管理深入理解Linux内核——内存管理
分配块释放快每CPU页框高速缓存1)这里为每个内存管理区和每个cpu提供了两个高速缓存:热高速缓存(存放的页框中所包含的内容很有可能就在CPU硬件高速缓存中);冷高速缓存。
e