遇到一个需求,需要在内核中统计mysql进程匿名页的访问热度。

配置系统环境

将透明大页关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled

寻找mysql的task_struct

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct task_struct *task = NULL;

//0:not found 1:found
int findMysql(void)
{
int ret = 0;
struct task_struct *proc;
for_each_process(proc){
if(!strcmp(proc->comm, "mysqld")){
task = proc;
ret = 1;
break;
}
}
return ret;
}

统计匿名页热度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int tem;
struct page *page = NULL;
struct page_cgroup *pc;
struct vm_area_struct *vma;
unsigned long addr = 0;

for(vma = task->mm->mmap; vma != NULL; vma = vma->vm_next){
for(addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE){
page = follow_page(vma, addr, 0);
if (page && PageAnon(page)){
pc = lookup_page_cgroup(page);
tem = page_referenced(page, 0, pc, &vm_flags) ? 1 : 0;
sprintf(str_buf, "22222222:%ul:%d\n", page_to_pfn(page), tem);
write_to_file((void *)str_buf, strlen(str_buf));
}
}
}