合并-khugepaged

当THP功能打开后,内核会启动一个专门的线程khugepaged,将原本不是大页的页表合并成大页。

加入扫描队列

khugepaged作为一个线程会不停扫描自己的队列,看是否有需要合并的内存。我们先来看看这个队列的结构。

    khugepaged_scan
    +---------------------------+
    |address                    |  当前扫描到的虚拟地址
    |   (unsigned long)         |
    |mm_slot                    |  当前正在扫描的进程信息
    |   (khugepaged_mm_slot *)  |
    |   +-----------------------+
    |   |slot                   |
    |   |   (struct mm_slot)    |
    |   |   +-------------------+
    |   |   |mm                 |  指向进程的mm_struct
    |   |   |                   |
    |   |   |mm_node            |  添加到khugepaged_scan.mm_head的节点
    |   |   | (struct list_head)|
    |   |   |hash               |  添加到mm_slots_hash表的节点
    |   |   | (hlist_node)      |
    |   +-----------------------+
    |                           |
    |mm_head                    |  一个用于存放khugepaged_mm_slot.slot的链表
    |   (struct list_head)      |
    |                           |
    +---------------------------+

    mm_slots_hash
    +---------------------------+
    |                           |  一个用于存放khugepaged_mm_slot.slot的hash表
    +---------------------------+

将需要扫描的进程加入队列的函数是khugepaged_enter_vma()。每次都会分配一个khugepaged_mm_slot结构,然后将这个结构添加到khugepaged_scan.mm_head和mm_slots_hash中。

进程级扫描

khugepaged的扫描可以分为两个级别

  • 进程级

  • vma级

首先我们来看进程级扫描,khugepaged_scan_mm_slot()。这个级别主要是在遍历khugepaged.mm_head。

初始的时候,khugepaged_scan.mm_slot是空的,所以它会从khugepaged.mm_head上取下一个,写到khugepaged.mm_slot,开始做vma级扫描。

当这个进程的所有vma都扫描完后,则从khugepaged.mm_head上取出下一个,循环往复。

vma级扫描

Last updated