p = alloc_pages(GFP_KERNEL, 2);
复合页根本就不会在页缓存中使用。
可以使用PageCompound函数来检测一个页是否是复合页,另外函数PageHead
和函数PageTail用来检测一个页是否是页头或者页尾。在每个尾页的page
结构体中都包含一个指向头页的指针 - first_page,可以使用compound_head
函数获得。
那么当一个复合页不再被系统使用时,我们如何知道该复合页包含多少
个普通页,又如何知道该复合页的析构函数(destructor)存在哪里呢?
首先,人们可能会认为这些信息存在于头页的page结构体中,但是很不
幸,在这个结构体中已经没有可用的空间了。因此,这些信息全部存储
在第一个尾页的lru字段中,将该复合页的大小(order)首先强制转换
为指针类型,然后存储在lru.prev中,将析构函数存储在lru.next中。
这里就解释了为什么复合页必须至少是两个页。
在内核中生命了两个复合页的析构函数,默认情况下会调用free_compound_page
来将所有的页返回给系统的页框分配器,而hugetlbfs子系统会调用free_huge_page
来做一些统计并释放。
使用复合页的最经典的一个例子就是THP(transparent huge page),
另外一些驱动使用复合页来方便缓存的管理。
ref
===
1. https://lwn.net/Articles/619514/