1、复合页的定义:

  复合页(Compound Page)就是将物理上连续的两个或多个页看成一个独立的大页,它可以用来创建hugetlbfs中使用的大页(hugepage),  也可以用来创建透明大页(transparent huge page)子系统。但是它不能用在页缓存(page cache)中,这是因为页缓存中管理的都是单个页。

2、复合页的分配及标记:

  当__alloc_pages分配标志gfp_flags指定了__GFP_COMP,那么内核必须将这些页组合成复合页compound page。复合页的尺寸要远大于当前分页系统支持的页面大小。并且一定是2^order * PAGE_SIZE大小。复合页主要用在HugeTLB相关的代码。复合页的引入是因为随着计算机物理内存容量不断增大,4G以上几乎成了标配,几十G的内存也很常见,而操作系统仍然使用4KB大小页面的基本单位,显得有些滞后。当采用4KB大小的页面时,想像一下当应用程序分配2MB内存,并进行访问时,共有512个页面,操作系统会经历512次TLB miss和512次缺页中断后,才可以把这2M地址空间全部映射到物理内存上;然而如果使用2MB大小的compand页,那么只需要一次TLB miss和一次缺页中断。当页面分配函数使用GFP_COMP进行页面分配时,分配函数会为每一个增加标志PG_Compound,我们称复合页中的第一个4KB页面为head page,后面的所有page 为tail page。每个page的private保存一个指针,head page的private指向本身,tail page的private指向head page。

  Page页中的flag标记用来识别复合页。在复合页中,打头的第一个普通页成为“head page”,用PG_head标记,而后面的所有页被称为“tail pages”,用PG_tail标记。在64位系统中,可以有多余的标记来表示复合页的页头和页尾;但是在32位系统中却没有那么多的标记,因此采用了一种复用其他标记的方案,即将复合页中的所有页都用PG_compound标记,然后,对于尾页同时也使用PG_reclaim标记,这是因为PG_reclaim只有在页缓存中会用到,而复合页根本就不会在页缓存中使用。

 //32位系统中的标记实例: 
1 #define PG_head_mask ((1L << PG_compound))
2 #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
3
4 static inline int PageHead(struct page *page)
5 {
6 return ((page->flags & PG_head_tail_mask) == PG_head_mask);
7 }
8
9
10 static inline int PageTail(struct page *page)
11 {
12 return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask);
13 }

3、复合页的检测:

  可以使用PageCompound函数来检测一个页是否是复合页,另外函数PageHead和函数PageTail用来检测一个页是否是页头或者页尾。在每个尾页的page结构体中都包含一个指向头页的指针 - first_page,可以使用compound_head函数获得。

 

4、复合页的释放:

  那么当一个复合页不再被系统使用时,我们如何知道该复合页包含多少个普通页,又如何知道该复合页的析构函数(destructor)存在哪里呢?首先,人们可能会认为这些信息存在于头页的page结构体中,但是很不幸,在这个结构体中已经没有可用的空间了。因此,这些信息全部存储在第一个尾页的lru字段中,将该复合页的大小(order)首先强制转换为指针类型,然后存储在lru.prev中,将析构函数存储在lru.next中。

 1 static void free_compound_page(struct page *page)
2 {
3 __free_pages_ok(page, compound_order(page));
4 }
5
6 static inline int compound_order(struct page *page)
7 {
8 if (!PageHead(page))
9 return 0;
10 return (unsigned long)page[1].lru.prev;
11 }

  这里就解释了为什么复合页必须至少是两个页。在内核中生成了两个复合页的析构函数,默认情况下会调用free_compound_page来将所有的页返回给系统的页框分配器,而hugetlbfs子系统会调用free_huge_page来做一些统计并释放。使用复合页的最经典的一个例子就是THP(transparent huge page),

linux 复合页( Compound Page )的介绍的更多相关文章

  1. 复合页( Compound Page )

    复合页(Compound Page)就是将物理上连续的两个或多个页看成一个      独立的大页,它能够用来创建hugetlbfs中使用的大页(hugepage).      也能够用来创建透明大页( ...

  2. 大页(Huge Page)简单介绍

    x86(包括x86-32和x86-64)架构的CPU默认使用4KB大小的内存页面(getconf PAGESIZE),但是它们也支持较大的内存页,如x86-64系统就支持2MB大小的大页(huge p ...

  3. Linux内存管理 (11)page引用计数

    专题:Linux内存管理专题 关键词:struct page._count._mapcount.PG_locked/PG_referenced/PG_active/PG_dirty等. Linux的内 ...

  4. 【原创】(十四)Linux内存管理之page fault处理

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  5. 为什么Linux默认页大小是4KB

    本文转载自为什么 Linux 默认页大小是 4KB 导语 我们都知道 Linux 会以页为单位管理内存,无论是将磁盘中的数据加载到内存中,还是将内存中的数据写回磁盘,操作系统都会以页面为单位进行操作, ...

  6. [转载]linux段页式内存管理技术

    原始博客地址: http://blog.csdn.net/qq_26626709/article/details/52742470 一.概述 1.虚拟地址空间 内存是通过指针寻址的,因而CPU的字长决 ...

  7. [转帖] 学习 Linux 大页的内存知识

    一.在解释什么情况下需要开启大页和为啥需要开启大页前先了解下Linux下页的相关的知识:以下的内容是基于32位的系统,4K的内存页大小做出的计算1)目录表,用来存放页表的位置,共包含1024个目录en ...

  8. Linux系统中的Page cache和Buffer cache

    Linux系统中的Page cache和Buffer cache Linux中有两个很容易混淆的概念,pagecache和buffercache,首先简单将一些Linux系统下内存的分布,使用free ...

  9. linux中读写锁的rwlock介绍-nk_ysg-ChinaUnix博客

    linux中读写锁的rwlock介绍-nk_ysg-ChinaUnix博客 linux中读写锁的rwlock介绍 2013-02-26 13:59:35 分类: C/C++   http://yaro ...

  10. 刨根究底字符编码之七——ANSI编码与代码页(Code Page)

    ANSI编码与代码页(Code Page) 一.ANSI编码 1. 如前所述,在全世界所有国家和民族的文字符号统一编码的Unicode编码方案问世之前,各个国家.民族为了用计算机记录并显示自己的字符, ...

随机推荐

  1. Vulhub 漏洞学习之:AppWeb

    Vulhub 漏洞学习之:AppWeb 目录 Vulhub 漏洞学习之:AppWeb 1 AppWeb认证绕过漏洞(CVE-2018-8715) 1.1 漏洞利用原理 1.2 漏洞利用过程 1 App ...

  2. 达标式减量策略又一例证(STRASS研究)

    标签: 类风湿关节炎; T2T策略; TNF抑制剂; 药物减停; STRASS研究 达标式减量策略又一例证(STRASS研究): RA维持期个体化减停TNF拮抗剂是可能的 电邮发布日期: 2016年1 ...

  3. select去除默认样式

    select { /*Chrome同Firefox与IE里面的右侧三角显示的样式不同*/ border: solid 1px #ddd; /*将默认的select选择框样式清除*/ appearanc ...

  4. STM32L431 移植 LiteOS 时 _ebss _Min_Heap_Size _Min_Stack_Size 未找到或未定义

    将 LiteOS 移植完成之后,编译报如下错误: 环境 版本 Keil V5.37.0.0 Windows11 2022/12/22 ARM::CMSIS 5.9(2022-05-22) 开发板 ST ...

  5. Cesium之Quick Start

    1. 引言 Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业 ...

  6. tp-link路由器后台_硬解

    title: 脚本_tp-link路由器后台_硬解 author: 杨晓东 permalink: 脚本 date: 2021-10-02 11:27:04 categories: - 投篮 tags: ...

  7. Vulnhub:vulnuni1.0.1靶机

    kali:192.168.111.111 靶机:192.168.111.192 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...

  8. Redis Stream类型的使用详解

    目录 一.背景 二.redis中Stream类型的特点 三.Stream的结构 四.Stream的命令 1.XADD 往Stream末尾添加消息 1.命令格式 2.举例 2.XRANGE查看Strea ...

  9. PO培训

    30M 的step by step.带notes  这个文档把常用的包含java都有 不止是配置,反正各种处理都有.. 各种高清无码截图,还不算附件内容

  10. C++程序设计实验二 数组、指针与C++标准库

    Info.hpp文件源码 #include<iostream> #include<string> #include<iomanip> using namespace ...