32 Cow of physical pages in linux

foreword

Anyone who is familiar with the linux process mechanism knows that a new process in linux is a process created in the form of fork + exec 

When fork, the relevant data structure of the parent process is copied, and then the binary to be executed is updated to execute  

Then the memory management between the parent and child processes is based on copy on write 

For a physical page, after fork, the memory is set to read-only, and then when a write request occurs, the physical page is copied, and then the operation is performed 

test case

The use case is mainly to apply for a piece of space, and then set it to aaa 

Then fork, a single process becomes a parent-child process, and then the parent process sets the space to bbbb, and the child process sets the space to ccccc 

Here is the process of debugging our cow above 

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"

void processHandler(int pid, char *p1, char *processName) {
    printf(" %s - %d, p1 : 0x%x, %s \n", processName, pid, p1, p1);
}

int main(int argc, char **argv) {

    char *p1 = (char *) malloc(20);
    memset(p1, 'a', 16);
    printf(" %s - %d, p1 : 0x%x, %s \n", "parent", getpid(), p1, p1);

    int childPid = fork();
    sleep(rand() % 5);
    if (childPid == 0) {
        memset(p1, 'b', 16);
        processHandler(getpid(), p1, "child1");
    } else {
        memset(p1, 'c', 16);
        processHandler(getpid(), p1, "parent");
    }

}

cow The parent process and child process page table entries are set to read-only

First disable ASLR, in this relatively small case, malloc calls brk to apply for the first block space, the first address will be 0x602000 

The place where the page table entries of the parent process and the child process are set to read-only is here 

You can see the range of this vma in copy_pte_range, [6299648 - 6434816] is [0x602000 - 0x6230000] The space we malloc applied for belongs to this vma 

When the parent process/child process modifies the content of the corresponding page, cow copies the physical page

According to our current rules here, one execution will generate two processes, and no other processes will be generated 

The parent process is odd and the child process is even 

Here is where the parent/child process tries to modify the space where [0x602000 - 0x6230000] is located, and then the related processing of the kernel 

The process that modifies first copies the original physical page and sets it as readable and writable, and then the corresponding process operates the given physical page 

The post-modification process finds that only the current process can use the physical page, and directly reuse the physical page 

The copying of physical pages is based on kmap_atomic + memcpy 

The process number of the first operation here is 313, which corresponds to the parent process 

The post-modification process finds that only the current process can use the physical page, and directly reuse the physical page 

(initramfs) ./Test23MemoryCowChildFirst 
 parent - 313, p1 : 0x602010, aaaaaaaaaaaaaaaa 
 child1 - 314, p1 : 0x602010, bbbbbbbbbbbbbbbb 
 parent - 313, p1 : 0x602010, cccccccccccccccc 

The first operation here is when the child process first modifies the corresponding read-only page 

(initramfs) ./Test23MemoryCowChildFirst 
 parent - 319, p1 : 0x602010, aaaaaaaaaaaaaaaa 
 child1 - 320, p1 : 0x602010, bbbbbbbbbbbbbbbb 
 parent - 319, p1 : 0x602010, cccccccccccccccc 

over

reference

Explain in detail the COW mechanism of the Linux kernel copy-on-write technology (tear the source code by hand)

Guess you like

Origin blog.csdn.net/u011039332/article/details/128170093