这个问题与以下问题相关: 在fork进程时,为什么Linux内核要为每个新创建的进程复制内核页表的内容?
我发现Linux内核试图通过在函数
pgd_alloc
中将swapper页表的内容复制到每个新创建的页表中来避免在用户空间和内核空间之间切换时更新ARM TTBR。问题是:更新ARM TTBR有什么缺点?pgd_alloc
中将swapper页表的内容复制到每个新创建的页表中来避免在用户空间和内核空间之间切换时更新ARM TTBR。问题是:更新ARM TTBR有什么缺点?在使用MMU启用时更新TTBR
(翻译表基址寄存器)Note1存在许多风险。需要考虑中断、页故障、TLB(MMU缓存)以及L1和L2缓存。在不同系统上,缓存可能是PIPT或VIVT(物理或虚拟标记),可能不存在L1或L2缓存。
人们似乎过于关注MMU和TLB的效率。在性能考虑中,它们总是被主要的L1/L2缓存所压倒。更新MMU表并执行TLB刷新的影响要小于从L1/L2代码和数据缓存中进行不必要的逐出。至少一个TLB值得1/4KB或超过1/100个缓存行(重新填充的成本)。在某些情况下,TLB条目可能为1MB。
在上下文切换时,L1/L2用户空间中的某些数据/代码可能需要被清除。但是,对于非常频繁的小工作负载,用户上下文切换可能会使代码和数据保留在L1/L2中。例如,媒体播放器执行大量CPU密集型解码以及检查服务器上是否有新电子邮件的cron任务。切换到“cron”任务并返回可能导致代码仍然在L2缓存中供视频解码使用。
switch_to()
和finish_task_switch()
都完成后,用户空间才能真正活动起来。只有在CPU模式切换之前需要switch_to()
部分是原子/被锁定的。 - artless noise