SMP(对称多处理器/多核)机器上的中断是如何处理的?是否只有一个或多个内存管理单元?
假设运行在不同内核上的两个线程 A 和 B (同时)接触到页表中不存在的内存页,在这种情况下将出现页面错误,并从内存中引入新页。
将发生的事件的顺序是什么?如果有一个内存管理单元,页面错误转发到哪个核心?内核如何处理它?是否有多个内核实例,每个实例都运行在不同的内核上?如果是这样,它们如何在页面错误处理等事件上同步?
好吧,这取决于具体的架构,但从我能从英特尔文档中记住的...
有两个主要的中断源:
内部中断总是传递给产生它的 CPU。外部的被发送到任意核心。
在现代模型中,中断也可以使用类似总线的系统而不是旧的中断驱动系统来传递,但我忽略了这个模型是否正在任何当前的操作系统中使用。
关于MMU,当然,每个核心都有自己的,但它们通常被操作系统强制相同的段,因此它们可以对称使用。请注意,物理内存和虚拟内存之间的大部分映射实际上都在内存中,并且始终是共享的。
关于您示例中的序列:
在多核/多处理器架构上,APIC用于将中断路由到内核/处理器。顾名思义,APIC 可以被编程为根据需要进行路由。
关于内核的同步:这取决于内核/操作系统。您可以使用带有锁定的方案(尽管在非缓存一致的架构上可能需要 IPI),或者您也可以使用建议的方法在每个内核上运行内核并使用某种显式的内核间通信。
Barrelfish是运行多个内核的操作系统的一个示例。如果您对这种架构感兴趣,您可能想阅读论文“多内核:可扩展多核系统的新操作系统架构”
每个处理器都有自己的内存管理单元和翻译后备缓冲区。这是必要的,因为每个内核可能正在执行具有不同地址空间的不同进程。
多个内核可以同时独立处理中断/异常。因此可以在内核中同时执行多个并发中断上下文。
诸如页面错误或被零除之类的异常将始终在发生它的同一处理器上处理,因为它与该处理器正在执行的操作有关。
外部中断通常通过某种交换结构,允许它们以某种方式静态或动态映射到处理器。例如,PC 型硬件上的“APIC”。
如果结构足够复杂,则可以针对不同的内核即时重新编程中断。
这取决于架构。例如,一个简单的架构可以将所有外部中断绑定到一个内核。不过那不是很对称;它不允许 IRQ 负载平衡。
(另请注意,在所有处理器上发生某些外部中断是很有用的。定时器中断就是一个例子。如果每个内核都有自己的中断定时器,那么调度程序中的时间片处理是对称的:没有特殊情况处理对于一个主核心与其他核心。中断发生,核心运行调度程序代码,如果当前任务的时间量已到,它会选择另一个任务在该核心上运行。)
每个逻辑 CPU(即 CPU 内核)都有自己的cr3
寄存器,用于处理指向分页结构的指针。两种页面错误都可能发生:
如果这些是不同进程的线程,那没问题。我不知道 Linux 对此的具体实现是什么(是的,我知道它被标记为“linux”),但是在 SMP 环境中管理虚拟内存有两种通用算法:
相同的代码(#PF 处理程序)可以在两个不同的内核上同时执行,这不是问题。如果线程使用两个不同的 VASes 1,那么它们的页面错误只是对称地处理。如果页面错误发生在单个VAS内,仍然没有问题,直到#PFs是由访问同一页面引起的。在这种情况下,VAS 中的每个页面都应该受到自旋锁的保护(或者仅给定 VAS 中的 #PF 可以受到单个锁的保护——这种方式减少了内存开销,但消除了同时运行两个 #PF 处理程序的可能性)。
根据this answer,仅在NUMA系统中,每个CPU内核都有自己的MMU;在其他系统中,每个物理处理器都有自己的 MMU,以及 TLB 来处理由不同cr3
寄存器值引用的不同分页结构。
1. VAS = 虚拟地址空间
我没有得到“内核的多个实例”,通常是内核规则全部。这意味着它没有实例,而是应该将内核视为一个全局反应系统,它为应用程序提供服务。
据我所知,内存处理是一个单元(虽然每个内核都有自己的中断向量),页面是使用 锁定的page_table_lock
,所以页面检索只执行一次,按照锁定的顺序。
** 编辑:看到其他评论后,我的回答可能已经过时了:无论如何你应该检查:http ://www.xml.com/ldd/chapter/book/ch13.html