【发布时间】:2015-01-29 02:01:54
【问题描述】:
以下讨论适用于 32 位 ARM Linux 内核。
我注意到在fork过程中,Linux内核将内核页表(master page table,即swapper_pg_dir)的内容复制到每个新创建的进程的页表中。
问题是:
- 为什么要这么做呢?
- 为什么所有进程不能共享一个内核页面副本 表(关于 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));
【问题讨论】:
-
只有一个物理MMU;它是硬件。每个进程都需要一个完整的 1 级表 (16K)。对于内核,大多数是节/超节,大小为 1MB,没有 L2。进程可以共享 L2 条目。
-
感谢您的评论。你的意思是说因为只有一个物理MMU,如果内核母版页表(swapper page table)只有一个副本,那么每次内核/用户模式切换时都需要刷新MMU?
-
不,每个进程可能有一个连续的 16k 单独的 L1 表。切换表底座时,必须刷新所有 L1-TLB。但是,我认为 Linux 只更新 real L1 页表,并为每次更新进行 TLB 刷新;在 ARM 上有一些假的页表。抱歉,我没有看什么是 swapper_pg_dir;真实表或伪表。 Linux 有 arch 依赖/独立代码。
-
所以我的理解是如果 -所有进程共享相同的内核母版页表的单个副本以用于较高的 1GB 部分(内核土地)-所有进程对较低的 3GB 部分使用单独的页表(用户空间) 这意味着进程没有连续的 16K L1 表,因此每次内核-用户切换时都需要切换页表。 请您确认一下吗?谢谢!
-
您好,从源码看,内核页表没有完全复制。实际上只拷贝了page全局目录,也就是说进程页表和内核页表指向同一个pud、pmd和pte。
标签: c linux memory-management linux-kernel arm