page compaction原理

参考: https://lwn.net/Articles/368869/

先看一个例子: 

如果你的ubuntu机器经过长时间运行,比如1个月没关机,这时候你去看buddinfo和pagetypeinfo的信息。

root@root# cat /proc/buddyinfo
Node 0, zone      DMA      3      3      1      1      3      2      0      0      1      1      3
Node 0, zone    DMA32  12996   3696   1157     87     24      6      0      0      0      0      0
Node 0, zone   Normal  82836  13398   1269    269      8      1      0      0      0      0      0


root@root# 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      3      1      1      3      2      0      0      1      0      0
Node    0, zone      DMA, type      Movable      0      0      0      0      0      0      0      0      0      1      3
Node    0, zone      DMA, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone      DMA, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone      DMA, type          CMA      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone      DMA, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type    Unmovable    568    212    115     60     24      6      0      0      0      0      0
Node    0, zone    DMA32, type      Movable  12389   3475   1040     27      0      0      0      0      0      0      0
Node    0, zone    DMA32, type  Reclaimable     39      9      2      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type          CMA      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone   Normal, type    Unmovable     88    161    288     45      1      1      0      0      0      0      0
Node    0, zone   Normal, type      Movable  82530  13055    902    159      0      0      0      0      0      0      0
Node    0, zone   Normal, type  Reclaimable    311    182     52     51      2      0      0      0      0      0      0
Node    0, zone   Normal, type   HighAtomic      0      0     27     14      5      0      0      0      0      0      0
Node    0, zone   Normal, type          CMA      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone   Normal, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
 
Number of blocks type     Unmovable      Movable  Reclaimable   HighAtomic          CMA      Isolate
Node 0, zone      DMA            1            7            0            0            0            0
Node 0, zone    DMA32           15          882          119            0            0            0
Node 0, zone   Normal          148         6679          312            1            0            0

可以很明显看见order=0的页很多,而order逐渐增大的发现页越来越少。比如order=10的页在Noraml中已经没有了。

这就导致了一个问题:

当我们需要申请一大块连续的物理内存的时候,就会出现无法找到一个连续的大块内存,剩下的大多数都是一页一页零散的内存了。这种问题就是内存碎片问题了。

为了解决内存碎片问题,linux内核引入了page compaction技术,俗称页块整理。整理的原理如下:

假设现在有一个zone的内存布局内部如下:其中red 区域代表的是已经使用的,white是空闲的

可以清晰的看见,所属的空闲区域连续的最大是2个page。如果从该zone中分配四个连续的内存区域,就会出现必然失败的。有可能分配两个连续的页面也有可能失败,如果考虑对齐的话。

page compaction的步骤:

  • 代码中运行两个独立分扫描队列,第一个扫描队列从zone的底部从下往上扫描,一边扫描一边讲可以移动(Moveable)的页放入到此链表中,可以将此链表称为迁移扫描器

  • 同时在zone的顶部页存在一个扫描器(空闲扫描器),从顶部到底部将空闲的页假如到空闲链表中。

  •  当迁移扫描器从底部到顶部扫描,空闲扫描器从顶部到底部扫描,最终迁移和空闲扫描器最终会相遇。当迁移扫描器和空闲扫描器相遇之后,就意味着page compaction结束了。剩下的工作就是将迁移扫描器的page copy到空闲扫描器,然后接触迁移扫描器的页面对应关系。最终会形成如下的结果 

  这样一来我们就拥有了一个连续的8页的可用空间了。可以满足更高阶的分配需求了。

   当然page compation有两种触发方式:

  •   当分配page的时候,在LOW水位出现分配失败的时候,会尝试slowth分配的,在当中就会出现page compaction的流程
  • 工程师可以通过echo x > /proc/sys/vm/compact_memory来启动page compaction的动作,启动后内核线程kcompactd*就会启动来进行页面整理的

此时当我在ubuntu上执行echo 1 > /proc/sys/vm/compaction_memory的时候,ubuntu就会启动kcompactd0内核线程来执行页面整理的。咋们来看下最后的结果

root@root# 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      3      1      1      3      2      0      0      1      0      0
Node    0, zone      DMA, type      Movable      0      0      0      0      0      0      0      0      0      1      3
Node    0, zone      DMA, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone      DMA, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone      DMA, type          CMA      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone      DMA, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type    Unmovable    186    129     98     60     24      6      0      0      0      0      0
Node    0, zone    DMA32, type      Movable   1350   1320   1184    799    342     88      7      1      0      0      0
Node    0, zone    DMA32, type  Reclaimable     68     47     19      7      1      0      0      0      0      0      0
Node    0, zone    DMA32, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type          CMA      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone   Normal, type    Unmovable    318    473    493    244     17      1      0      0      0      0      0
Node    0, zone   Normal, type      Movable   7452   9250   7096   4037   1032     74      4      0      0      0      0
Node    0, zone   Normal, type  Reclaimable    621    406    321    211     20      1      0      0      0      0      0
Node    0, zone   Normal, type   HighAtomic      0      0     27     14      5      0      0      0      0      0      0
Node    0, zone   Normal, type          CMA      0      0      0      0      0      0      0      0      0      0      0
Node    0, zone   Normal, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
 
Number of blocks type     Unmovable      Movable  Reclaimable   HighAtomic          CMA      Isolate
Node 0, zone      DMA            1            7            0            0            0            0
Node 0, zone    DMA32           15          882          119            0            0            0
Node 0, zone   Normal          148         6679          312            1            0            0

root@root# cat /proc/buddyinfo                 
Node 0, zone      DMA      3      3      1      1      3      2      0      0      1      1      3
Node 0, zone    DMA32   1604   1496   1301    866    367     94      7      1      0      0      0
Node 0, zone   Normal   8422  10129   7937   4506   1074     76      4      0      0      0      0

可以看到order逐渐增加可以看见有很多空闲的page了。而且movebale order=0得也在减少,order=2, 3, 4 , 5在增加。这就说明了page compation还是有效的。

原创文章 204 获赞 130 访问量 38万+

猜你喜欢

转载自blog.csdn.net/longwang155069/article/details/105689556