Find which pages are no longer shared with copy-on

2020-06-23 09:53发布

问题:

Say I have a process in Linux from which I fork() another identical process. After forking, as the original process will start writing to memory, the Linux copy-on-write mechanism will give the process unique physical memory pages which are different from the one used by the forked process.

How can I, at some point of execution, know which pages of the original process have been copied-on-write?

I don't want to use SIGSEGV signal handler and give read only access to all the pages in the beginning as that induces an overhead I don't want.

回答1:

Tracing the syscall - fork(), clone():

copy_process()->copy_mm()->dup_mm()->dup_mmap()-->and here you will find the algorithm to go through VMA by VMA to mark them as "copy-on-write":

http://www.cs.columbia.edu/~krj/os/lectures/L17-LinuxPaging.pdf

http://www.cs.columbia.edu/~junfeng/13fa-w4118/lectures/l20-adv-mm.pdf

Essentially (refer to slides), if PTE in unwriteable (which is hardware-based), and VMA is marked as writeable (which is software based) - that means the memory is copy-on-write.

You can always write a kernel module to do that.



回答2:

You probably have to accept some overhead.

If you are privileged, you can pread /proc/self/pagemap (64 bits, at offset 8*(addr / PAGE_SIZE)) to get the PFN (it's the low 54 bits). Then look up that PFN in /proc/kpagecount to see if the page is shared.

If you don't have privilege, you can compare the PFN in the pagemap of the parent and child.

You can tell if any of the pages in the mapping are shared by comparing the Pss (proportional set size) with the total size in /proc/smaps.