当前位置: 首页 > news >正文

linux内存管理系统后期的内核对zonelist的简化

struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[GFP_ZONETYPES];
...
}
GFP_ZONETYPES是一个宏,在2.6.8的时候它如下定义:
#define GFP_ZONEMASK 0x07
/* #define GFP_ZONETYPES (GFP_ZONEMASK + 1) */
#define GFP_ZONETYPES ((GFP_ZONEMASK + 1) / 2 + 1)
也就是说每一个numa的node拥有算了一下5条zone链表,就这还算比较少了。
可是在高一点版本的内核中,这个本来已经很低的zonelists数量变成了2(支持numa)或者1(不支持numa),也许很多人会说,通过GFP标志已经无法控制在哪个zone中以及之下分配内存了,然而看一下get_page_from_freelist这个函数多了很多参数,其中一个high_zoneidx所起到的作用就是原来那么多zonelist的作用,由此可见,高版本的内核丝毫没有降低功能,倒是少维护很多链表。以下首先说一下早期的内核中的多条zonelist链表的起因以及为何那么设计。
在早期的内核中,每一个node拥有好几条zonelist,每一条代表一个起始zone开始的以及其下的所有的zone,但是这只是实际上的做法,而理论上这个zonelist的数量会更多,这些zonelist代表了一个优先级序列,说明了内存分配在zone中尝试的顺序,在实现中,linux是用位掩码来实现的。如果我们有三个zone,那么就应该用3位掩码中的每一个位来表示不同的zone掩码,设如下:
0x01表示dma
0x02表示normal
0x04表示highmem
这样3个位就有8*2...个顺序,分别是(o为空):
1.o;
2.dma;
3.normal->o;
4.normal->dma;
5.highmem->o;
6.highmem->o->dma;
7.highmem->normal->o;
8.highmem->normal->dma;
9-16.前面8个方向反过来。
17-xx.两两反向,保持一个正向...
可是为何内核仅仅保留了3个左右的顺序呢?首先是三个原则在起作用,第一个就是一致的顺序管理起来更高效而且更不容易冲突,类似单行道的作用,虽然灵活性不够!第二个原则就是内核的内存管理是一个管理机构,但凡内核的管理机构,采取的原则都是平等至上的!第三个原则就是连续性管理原则,按照一定的顺序依次编排,这个顺序一般都是从易到难,从受影响最小的地方开始,不到万不得已不会惊动其它。有了这三个原则的话,首先我们看一下为何没有反向顺序的zonelist,如果有的话就增加了管理负担,因为自动内存置换程序(kswapd)和手动置换程序(try_to_free...)就都要在两个方向进行扫描和管理,由于存在多条路径扫描和分配,这就很不容易了解到各个zone的内存使用情况,从而不知道要将扫描主力放在哪个zone。那么为何不存在跳跃的zonelist,比如跳过normal而仅仅在highmem和dma中分配,这是因为之所以存在一个zonelist而不是一个zone是因为在该zone中分配失败之后有一个后备的可分配zone,由于分配使用的zonelist使用的顺序必然是从容易分配的zone到难分配的zone排列的,那么dma中分配内存的代价会比normal中分配的代价更大。在linux操作系统的内存管理中,主要就是管理内核内存(包括驱动的内存)和进程内存,在大内存的机器上,大量的物理内存无法一一映射进内核地址空间的前HIGH兆,因此实际上对于大多数内核内存管理来讲,这些大量的内存对之意义不大,因此它们更多的被用于进程内存,进程内存是可以随意映射进自己的地址空间的,不要求映射的方式--比如线性映射,也不要求连续性。因此进程内存优先从highmem这个zone中分配,如果不行的话,则最好先在normal中看看,然后再往dma走。对于内核内存管理而言,在系统初始化的时候,一些核心的数据和代码已经映射完毕了,需要内存的大户都是驱动或者模块或者就是诸如进程管理和网络协议栈的动态部分,比如新申请了一个task_t结构体,或者新分配了一个sk_buff结构体等等,这些内存一般从normal区开始分配,这是因为使用normal区的内存可以线性映射进系统内核,操作起来更高效。由于没有谁拥有特权,所以大家都遵守一样的原则,从它所可以触及的最高zone(gfp_flags决定)依次尝试到最低的zone,如果不行则手工调用try_to_free...从该zonelist的开始zone开始释放一些内存,这样做真的是很简单很高效!内核之所以不通知用户进程和驱动就直接在某个zone为之分配了内存是因为zone是操作系统内存管理模块最低层的概念,进程或者驱动甚至都不应该知道有zone的存在,因此内核才可以采取遵循以上三个原则的策略将物理内存分为若干个zone,然后按照从高到低的顺序依次尝试分配内存,直到成功。
后期的内核将上述机制的实现改变了,每一个pglist_data在没有numa的情况下只有一条zonelist,按照上述的三个原则,其实没有必要搞那么多链表的,由于不存在跳跃,不存在逆向,因此只需要一个链表和一个上限值即可,每次分配内存的时候从这个上限值代表的zone往下开始尝试即可,这样就可以省去一些空间和管理费用,将事先设置好N条zonelist转为直到实际上分配内存的时候再确定上限:
struct page *__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
struct zonelist *zonelist, ...)
{ //参数中的zonelist其实就是那唯一的一条zonelist(没有numa的情况下)
enum zone_type high_zoneidx = gfp_zone(gfp_mask);
...
}
如此一来,high_zoneidx这个变量就可以作为一个限制值,在get_page_from_freelist的时候设置一个阀值,虽然__alloc_pages_nodemask函数增加了一些分量,但是时间一点也不损耗多少,取消了几个链表,运行时增加了几个指令周期,这也许(很可能)是值得的。

相关文章:

  • bzoj3809: Gty的二逼妹子序列
  • linux内核page结构体的PG_referenced和PG_active标志
  • 解決BufferedReader读取UTF-8文件中文乱码(转)
  • 问题以及发现问题和解决问题
  • bitmap格式分析(转)
  • 关于数组或集合中判断存在某个元素
  • kexec机制
  • Spring事务配置的五种方式
  • buffer_head和bio
  • 关于人脸识别,稀疏表示的若干论文的小结
  • asp.net——正则表达式
  • 开始iOS 7中自动布局教程(一)
  • POJ 1470 Closest Common Ancestors
  • S3C2440-中文手册
  • URAL 1779 F - The Great Team 构造
  • canvas 高仿 Apple Watch 表盘
  • codis proxy处理流程
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • java2019面试题北京
  • JavaScript中的对象个人分享
  • Java比较器对数组,集合排序
  • Joomla 2.x, 3.x useful code cheatsheet
  • js数组之filter
  • Linux gpio口使用方法
  • Phpstorm怎样批量删除空行?
  • Python进阶细节
  • ViewService——一种保证客户端与服务端同步的方法
  • vue-loader 源码解析系列之 selector
  • Web标准制定过程
  • 高性能JavaScript阅读简记(三)
  • 工程优化暨babel升级小记
  • 基于HAProxy的高性能缓存服务器nuster
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 深度解析利用ES6进行Promise封装总结
  • 思维导图—你不知道的JavaScript中卷
  • 提醒我喝水chrome插件开发指南
  • 一、python与pycharm的安装
  • (11)MSP430F5529 定时器B
  • (12)Hive调优——count distinct去重优化
  • (C#)一个最简单的链表类
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (十一)图像的罗伯特梯度锐化
  • (原創) 物件導向與老子思想 (OO)
  • .equals()到底是什么意思?
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .net core 6 集成 elasticsearch 并 使用分词器
  • @Data注解的作用
  • [20171113]修改表结构删除列相关问题4.txt
  • [20190401]关于semtimedop函数调用.txt
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [Android]Tool-Systrace
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [AutoSAR系列] 1.3 AutoSar 架构
  • [BZOJ2208][Jsoi2010]连通数
  • [CSS] - 修正IE6不支持position:fixed的bug