- sysfs
- 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>
- dd if=/dev/zero of=ksm.dat bs=1M count=100
- gcc mergeable. c-o mergeable
- ./mergeable ksm.dat
- head/sys/kernel/mm/ksm/*
sysfs
KSM可以使用/sys/kernel/mm/ksm/下的特殊文件来进行设置(见表5-4)。
可以认为,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页应该是不能合并的。
图 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<==
在RHEL6中,由ksmtuned(Kernel Samepage Merging(KSM)Tuning Daemon)定期地将pages_to_scan等改变为适当的值。