在“分叉”进程的同时,为什么Linux内核为每个新创build的进程拷贝内核页表的内容呢?

以下讨论适用于32位ARM Linux内核。

我注意到,在分叉过程中,Linux内核将内核页表(master page table,即swapper_pg_dir )的内容复制到每个新创build进程的页表中。

问题是:

  • 为什么打扰呢?
  • 为什么不能为每个新创build的进程共享单个内核页表副本(关于32位ARM Linux的更高的1G部分),而不是memcpy交换页表?
  • 这是浪费内存吗?

相关源代码(“ – >”代表函数调用):
do_fork – > copy_process – > copy_mm – > dup_mm – > mm_init – > mm_alloc_pgd – > pgd_alloc – >

/* * Copy over the kernel and IO PGD entries */ init_pgd = pgd_offset_k(0); memcpy(new_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 

每个进程有自己的核心部分页表(高于1GB)的页表副本,以避免在切换用户/内核域时切换L1页表转换(即避免更新TTBR)。 请注意,用户/内核的切换发生得相当频繁。

为什么要避免更新TTBR? 详细信息可以在这里找到: 更新ARM TTBR(转换表基址寄存器)的缺点是什么?

共享页面表意味着共享内存空间。 换句话说,它打破了拥有操作系统的观点。 每个进程都有自己的页面故事。 页表不占用太多的内存。