C 查找哪些页面不再与写入时复制共享

C 查找哪些页面不再与写入时复制共享,c,linux,x86-64,copy-on-write,page-tables,C,Linux,X86 64,Copy On Write,Page Tables,假设我在Linux中有一个进程,其中我fork()有另一个相同的进程。在forking之后,由于原始进程将开始写入内存,Linux写时拷贝机制将为进程提供唯一的物理内存页,这与fork进程使用的物理内存页不同 在执行时,我如何知道原始流程的哪些页面在写入时被复制? 我不想使用SIGSEGV信号处理程序并在开始时为所有页面提供只读访问权限,因为这会产生我不想要的开销。您可能必须接受一些开销 如果您有特权,您可以预加载/proc/self/pagemap(64位,偏移量8*(addr/PAGE_SI

假设我在Linux中有一个进程,其中我
fork()
有另一个相同的进程。在
fork
ing之后,由于原始进程将开始写入内存,Linux写时拷贝机制将为进程提供唯一的物理内存页,这与fork进程使用的物理内存页不同

在执行时,我如何知道原始流程的哪些页面在写入时被复制?


我不想使用SIGSEGV信号处理程序并在开始时为所有页面提供只读访问权限,因为这会产生我不想要的开销。

您可能必须接受一些开销

如果您有特权,您可以预加载/proc/self/pagemap(64位,偏移量8*(addr/PAGE_SIZE))以获取PFN(低54位)。然后在/proc/kpagecount中查找该PFN,查看页面是否共享

如果您没有权限,可以在父级和子级的页面映射中比较PFN

通过比较Pss(按比例设置大小)与/proc/smap中的总大小,可以判断映射中是否有任何页面共享。

跟踪syscall-fork(),clone():

copy_process()->copy_mm()->dup_mm()->dup_mmap()-->在这里,您将找到通过VMA的算法,VMA将它们标记为“写入时复制”:

基本上(请参阅幻灯片),如果PTE为不可写(基于硬件),而VMA标记为可写(基于软件),则表示内存为写时拷贝。


你总是可以编写一个内核模块来实现这一点。

我怀疑这是在内核的一个非常深层次上完成的,应该会对你有所帮助。嗯,我认为写时复制听起来更好。你为什么要这样做?只是好奇吗?因为如果不是,并且您正计划实际使用它,那么听起来您需要重新考虑您的应用程序设计……getrusage()将为您提供rss和输入/输出的块数。如果您现在想知道哪些块出现了故障(“存在”),我想这是您自己的问题。是否有一种现有的机制供用户空间进程收集这些信息?这听起来很理想:除了查找哪些页面仍然共享,哪些页面没有共享之外,没有任何额外的开销。呃,我想可能不存在任何机制,因为您建议为它编写一个内核模块。目前还不确定:但您可能可以使用/proc//pagemap(对于PTE)+/proc/vmallocinfo(对于VMA)来提取信息。请参阅Documentation/vm/pagemap.txt