sysfs

KSM可以使用/sys/kernel/mm/ksm/下的特殊文件来进行设置(见表5-4)。

sysfs - 图1

可以认为,pages_sharing与pages_shared的比值越高,KSM的效果越明显。相反,如果这个比值较低,则表示即使进行扫描也无法进行页面合并。接下来,在例子程序(mergeable.c)中确认运行情况。


cat mergeable.c

include<stdio.h>

include<string.h>

include<unistd.h>

include<sys/mman.h>//for madvise

include<sys/types.h>

include<sys/stat.h>

include<fcntl.h>

include<stdlib.h>

include<time.h>

int main(int argc, char*argv[])

{

int fd=0;

char*file=NULL;

char filename[64]="";

struct stat stat;

if(argc<2){

printf("Usage:%s[file]\n",argv[0]);

return 1;

}

strcpy(filename, argv[1]);

if((fd=open(filename, O_RDWR|O_CREAT,0664))<0){

printf("Could not open file\"%s\"with O_RDWR",filename);

return 1;

}

if(fstat(fd,&stat)<0){

printf("Could not stat file\"%s\"",filename);

goto close;

}

if((file=(char*)mmap(NULL, stat.st_size, PROT_WRITE, MAP_PRIVATE,

fd,0))

==MAP_FAILED){

printf("Could not mmap file\"%s\"",filename);

goto close;

}

if(madvise((void*)file, stat.st_size, MADV_MERGEABLE)!=0){

printf("Could not madvise file\"%s\"",filename);

goto unmap;

}

memset(file,'1',stat.st_size);

memset(file,'2',stat.st_size/2);

memset(file,'3',stat.st_size/4);

memset(file,'4',stat.st_size/8);

/write random pages/

{

long long i, j;

int dpage_size=409620;/20 pages size*/

srand((unsigned int)time((time_t*)0));

for(i=0;i<dpage_size;i++)

{

j=rand();

file[i]=j;

}

}

printf("sleeping forever……\n");

while(1)

sleep(100);

madvise((void*)file, stat.st_size, MADV_UNMERGEABLE);

unmap:

munmap(file, stat.st_size);

close:

close(fd);

return 1;

}


在上例中向mmap指定了PROT_WRITE和MAP_PRIVATE。

在mmap的区域中写入20页的随机值(见图5-28)。这20页应该是不能合并的。

sysfs - 图2

图 5-28 mergeable.c的mmap区域映像

首先,使用dd命令生成100MB的文件。


dd if=/dev/zero of=ksm.dat bs=1M count=100


对mergeable.c进行编译。

gcc mergeable. c-o mergeable

指定dd命令生成的文件,执行进程。


./mergeable ksm.dat

head/sys/kernel/mm/ksm/*

==>/sys/kernel/mm/ksm/full_scans<==247

==>/sys/kernel/mm/ksm/pages_shared<==

0

==>/sys/kernel/mm/ksm/pages_sharing<==

0

==>/sys/kernel/mm/ksm/pages_to_scan<==


sysfs - 图3

在RHEL6中,由ksmtuned(Kernel Samepage Merging(KSM)Tuning Daemon)定期地将pages_to_scan等改变为适当的值。