最近需要修改linux内核代码中ksm部分,所以记录下遇到的一些重要函数,方便以后查阅与理解。

重要函数

PageTransHuge

函数原型:static inline int PageTransHuge(struct page *page)

函数功能: returns true for both transparent huge and hugetlbfs pages, but not normal pages.

PageTransCompound

函数原型: static inline int PageTransCompound(struct page *page)

函数功能: 如果page是透明大页,则返回true

page_trans_compound_anon

函数原型: static struct page * page_trans_compound_anon(struct page *page)

函数代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
static struct page *page_trans_compound_anon(struct page *page)
{
if (PageTransCompound(page)) {
struct page *head = compound_head(page);
/*
* head may actually be splitted and freed from under
* us but it's ok here.
*/
if (PageAnon(head))
return head;
}
return NULL;
}

函数功能: *head等于compound_head(page),如果PageAnon(head)则返回head,否则返回NULL

split_huge_page

函数原型: static inline int split_huge_page(struct page *page)

函数功能: splits huge page into normal pages;
Returns 0 if the hugepage is split successfully;
Returns -EBUSY if the page is pinned or if anon_vma disappeared from under us.

page_trans_compound_anon_split

函数原型: static int page_trans_compound_anon_split(struct page *page)

函数代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static int page_trans_compound_anon_split(struct page *page)
{
int ret = 0;
struct page *transhuge_head = page_trans_compound_anon(page);
if (transhuge_head) {
/* Get the reference on the head to split it. */
if (get_page_unless_zero(transhuge_head)) {
/*
* Recheck we got the reference while the head
* was still anonymous.
*/
if (PageAnon(transhuge_head))
ret = split_huge_page(transhuge_head);
else
/*
* Retry later if split_huge_page run
* from under us.
*/
ret = 1;
put_page(transhuge_head);
} else
/* Retry later if split_huge_page run from under us. */
ret = 1;
}
return ret;
}

函数功能: 拆分复合透明匿名页,若拆分成功返回0,否则返回非0


参考资料:

  1. 复合页

  2. ksm源码