Найти, какие страницы больше не доступны для копирования при записи
Скажем, у меня есть процесс в Linux, из которого я fork()
другой идентичный процесс. После fork
Поскольку исходный процесс начнет запись в память, механизм копирования и записи в Linux предоставит процессу уникальные страницы физической памяти, которые отличаются от тех, которые используются разветвленным процессом.
Как я могу в какой-то момент выполнения узнать, какие страницы исходного процесса были скопированы при записи?
Я не хочу использовать обработчик сигналов SIGSEGV и дать доступ только для чтения ко всем страницам в начале, так как это вызывает издержки, которые я не хочу.
2 ответа
Отслеживание системного вызова - fork (), clone ():
copy_process () -> copy_mm () -> dup_mm () -> dup_mmap () -> и здесь вы найдете алгоритм прохождения VMA через VMA, чтобы пометить их как "копирование при записи":
http://www.cs.columbia.edu/~krj/os/lectures/L17-LinuxPaging.pdf
http://www.cs.columbia.edu/~junfeng/13fa-w4118/lectures/l20-adv-mm.pdf
По существу (см. Слайды), если PTE не записывается (который основан на аппаратном обеспечении), а VMA помечен как доступный для записи (который основан на программном обеспечении) - это означает, что память является копируемой при записи.
Вы всегда можете написать модуль ядра для этого.
Вы, вероятно, должны принять некоторые накладные расходы.
Если у вас есть привилегии, вы можете использовать pread /proc/self/pagemap (64 бита, со смещением 8*(addr / PAGE_SIZE)), чтобы получить PFN (это младшие 54 бита). Затем найдите этот PFN в /proc/kpagecount, чтобы увидеть, является ли страница общей.
Если у вас нет привилегий, вы можете сравнить PFN в карте страницы родителя и потомка.
Вы можете определить, являются ли какие-либо страницы в отображении общими, сравнив Pss (размер пропорционального набора) с общим размером в / proc / smaps.