gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:23:27 25 4
gpt4 key购买 nike

当我使用 mmap 创建写时复制映射(MAP_PRIVATE)时,一旦我写入特定地址,就会复制此映射的某些页面。在我的程序中的某个时刻,我想弄清楚哪些页面实际上已经被复制了。有一个叫做'mincore'的调用,但它只报告页面是否在内存中,这与正在复制的页面是否相同。

有什么方法可以找出哪些页面已被复制?

最佳答案

很好,遵循MarkR的建议,我尝试通过 pagemap 和 kpageflags 界面。下面是一个快速测试,用于检查页面是否在调用时位于内存“SWAPBACKED”中。当然还有一个问题,那就是 kpageflags 只能由 root 访问的问题。

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 文件中检索这些页面。 读取文件/usr/src/linux/Documentation/vm/pagemap.txt

  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);
}
}
}

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

关于linux - 如何知道写时复制页面是否是实际副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4477666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com