全部博文(165)
分类: LINUX
2013-08-02 13:31:13
linux物理内存的管理采用的是经典的伙伴系统,当然也就存在伙伴系统的问题——内存碎片。
当然,此处的内存碎片问题并不算大,因为伙伴系统是以页为单位为管理内存的,碎片也是以“页”为单位,4k的物理内存还算不上是“碎片”。对于用户态的程序,几乎不需要超过4k的连续空间。但是对内核来说,碎片永远都不是好东西。某些硬件相关的操作会需要连续的物理内存,如果无法满足,内核就只能panic。另外,引入compaction的另一个重要因素就是使用hugepage。
4k的页面大小已经出现了很多年了,就像文件系统上1k-4k的block_size一样,都是适应二十年前硬件的容量与速度而出现的,对于现在的硬件来说它们都显得太小了。使用更大的物理页,可以带来两个好处:TLB缓存命中率的提高和page_fault的次数降低。compaction正是为了支持hugepage而出现的。
下面来看compaction的基本原理。
要获得连续的物理内存只有两个方法,直接释放掉一部分内存,或者重新组织内存。
在内核中的物理内存,有一部分是“可移动”的。
内核使用的反碎片技术的基本原理,就是根据页的“可移动性”将页面分组。
关于物理页的是否可移动
非空闲的 物理内存,当然要么是用户态进程在用,要么内核本身在用。对于前者,进程在访问物理内存的时候,实际上要通过页表的映射来访问。页表是一个可以做文章的地方:如果把一个页移动到另一个地方,如果可以同时修改页表,那么对应用程序就不会有影响。而对于内核访问物理内存时,是通过简单的常量偏移来做的。因此内核使用的物理页面无法移动。
页移动的流程:
1. 锁定页,以避免在移动页的过程中有进程修改页面。页面记为oldpage
2. 确保“writeback”已经完成
3. 删除当前页面的全部映射,并将指向该页的页表项标记MIGRATION
4. nbsp; 经过几天的艰苦奋战,终新页,记为newpage
5. 获取radix tree的锁,以阻塞所有试图通过radix tree来访问页面的进程。将radix tree中oldpage的指针指向newpage。释放radix tree的锁。
6. 旧页的内容被拷到新页面中,设置新页面的各项标志
7. 将所有页表项指向新页面
在页面移动过程中,old page是被锁定的。
另外,内核怎样知道一个页面是否是可移动的?
分配内存的函数,kmalloc,alloc_pages等在任何地方都可能被调用。内核又是怎样知道在这些地方分配的页面属于哪种类型呢?看这几个函数的原型
void *kmalloc(size_t size, gfp_t flags)
struct page * alloc_pages(gfp_t gfp_mask, unsigned int order)
内核自然不知道kmalloc分配的内存是作什么用途的,但是kernel 开发者知道,一个页面是否可移动,自然也是开发者们告诉内核的。gft_t中有个标志位:GFP_MOVABLE,开发者需要根据相应的内存是否要移动来设置该位。
那么该怎样查看系统中当前的碎片情况呢?/proc下已经提供了接口,一方面方便开发者调试,另一方面可以让系统管理员了解当前的系统运行状态。
gaoqiang@c2:~$cat /proc/pagetypeinfo
Page block order: 9
Pages per block: 512
Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
Node 0, zone DMA, type Unmovable 3 0 0 1 2 0 1 0 1 0 0
Node 0, zone DMA, type Reclaimable 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type Movable 0 0 0 0 0 0 0 0 0 0 3
Node 0, zone DMA, type Reserve 0 0 0 0 0 0 0 0 0 1 0
Node 0, zone DMA, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Unmovable 56 84 47 59 19 3 1 0 0 1 0
Node 0, zone DMA32, type Reclaimable 1 1 0 0 3 1 1 0 0 0 4
Node 0, zone DMA32, type Movable 57 33 23 10 4 3 9 18 11 3 2
Node 0, zone DMA32, type Reserve 0 0 0 0 0 0 0 0 0 0 1
Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Unmovable 398 398 171 48 28 8 0 0 0 0 0
Node 0, zone Normal, type Reclaimable 20 17 6 5 1 0 0 1 3 0 0
Node 0, zone Normal, type Movable 354 221 125 101 80 58 10 48 1 0 0
Node 0, zone Normal, type Reserve 2 3 1 2 2 2 2 2 2 0 0
Node 0, zone Normal, type Isolate 0 0 0 0 0 0 0 0 0 0 0