如何知道写时复制页面是否为实际副本?

当我使用mmap创建写时复制映射(MAP_PRIVATE)时,此映射的某些页面将在我写入特定地址后立即复制。在程序的某个时刻,我想弄清楚实际上已复制了哪些页面。有一个名为“

mincore”的调用,但仅报告该页面是否在内存中,这与正在复制的页面不同。

有什么办法可以确定哪些页面已被复制?

回答:

好的,按照MarkR的建议,我试了一下它来浏览pagemap和kpageflags界面。在一项快速测试下面,以检查页面是否在被调用时在内存中“SWAPBACKED”。当然,仍然存在一个问题,即kpageflags仅可由根访问的问题。

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

{

unsigned long long pagesize=getpagesize();

assert(pagesize>0);

int pagecount=4;

int filesize=pagesize*pagecount;

int fd=open("test.dat", O_RDWR);

if (fd<=0)

{

fd=open("test.dat", O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);

printf("Created test.dat testfile\n");

}

assert(fd);

int err=ftruncate(fd,filesize);

assert(!err);

char* M=(char*)mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_PRIVATE,fd,0);

assert(M!=(char*)-1);

assert(M);

printf("Successfully create private mapping\n");

测试设置包含4页。第0页和第2页脏了

  strcpy(M,"I feel so dirty\n");

strcpy(M+pagesize*2,"Christ on crutches\n");

已读取第3页。

  char t=M[pagesize*3];

第1页将无法访问

页面映射文件将进程的虚拟内存映射到实际页面,然后可以从全局kpageflags文件中检索该页面。

  int mapfd=open("/proc/self/pagemap",O_RDONLY);

assert(mapfd>0);

unsigned long long target=((unsigned long)(void*)M)/pagesize;

err=lseek64(mapfd, target*8, SEEK_SET);

assert(err==target*8);

assert(sizeof(long long)==8);

在这里,我们读取了每个虚拟页面的页面框架编号

  unsigned long long page2pfn[pagecount];

err=read(mapfd,page2pfn,sizeof(long long)*pagecount);

if (err<0)

perror("Reading pagemap");

if(err!=pagecount*8)

printf("Could only read %d bytes\n",err);

现在我们将为每个虚拟帧读取实际的页面标志

  int pageflags=open("/proc/kpageflags",O_RDONLY);

assert(pageflags>0);

for(int i = 0 ; i < pagecount; i++)

{

unsigned long long v2a=page2pfn[i];

printf("Page: %d, flag %llx\n",i,page2pfn[i]);

if(v2a&0x8000000000000000LL) // Is the virtual page present ?

{

unsigned long long pfn=v2a&0x3fffffffffffffLL;

err=lseek64(pageflags,pfn*8,SEEK_SET);

assert(err==pfn*8);

unsigned long long pf;

err=read(pageflags,&pf,8);

assert(err==8);

printf("pageflags are %llx with SWAPBACKED: %d\n",pf,(pf>>14)&1);

}

}

}

总而言之,我对这种方法并不特别满意,因为它需要访问我们通常无法访问的文件,而且它非常复杂(简单的内核调用来检索pageflags怎么样?)。

以上是 如何知道写时复制页面是否为实际副本? 的全部内容, 来源链接: utcz.com/qa/402967.html

回到顶部