我想知道Linux中x86_64有哪些不同种类的IPI。特别是,我想了解IPI中断的不同中断处理程序。
在Daniel P. Bovet,Marco Cesati所著的《理解Linux内核》第3版中。https:/www.oreilly.comlibraryviewunderstanding-the-linux0596005652ch04s06.html列出了三种IPI。
CALL_FUNCTION_VECTOR
RESCHEDULE_VECTOR
INVALIDATE_TLB_VECTOR
然而在最新的内核中,我在archx86includeasmentry_arch.h中找到了下面的注释。
* This file is designed to contain the BUILD_INTERRUPT specifications for
* all of the extra named interrupt vectors used by the architecture.
* Usually this is the Inter Process Interrupts (IPIs)
*/
/*
* The following vectors are part of the Linux architecture, there
* is no hardware IRQ pin equivalent for them, they are triggered
* through the ICC by us (IPIs)
https:/git.kernel.orgpubscmlinuxkernelgitstablelinux.gittreearchx86includeasmentry_arch.h?h=v5.6.15。
谁能确认一下文件中列出的所有这些Vectors是否是x86_64的不同类型的IPI.对于ARM,我可以找到一个统一的处理程序--handle_IPI()来处理所有的IPI。对于ARM来说,我可以找到一个统一的处理程序--handle_IPI()来处理所有的IPI。
关于x86 任何 中断向量可以被IPI触发,所以没有(或没有)指定的中断向量。
上图描述了用于发送IPI的寄存器的格式,即 固定 模式使用 矢量 字段,使目标CPU执行与该向量相关的中断服务例程。这就像一个 int vector
指令在目标中被执行。
所以Linux理论上可以直接调用其他任何CPU上的任何中断。但是,内核模块经常需要在特定的CPU上运行某个函数;所以Linux有一组实用函数,如 单个函数的调用 ,会让程序员的生活变得轻松。这些函数的实现机制值得单独写一章,现在我不知道细节,但不难想象背后的基本思想:有一个全局的函数执行队列和一个中断向量,一旦被调用,就会去掉一个项目并执行它。通过用IPI调用该中断向量,Linux可以让目标CPU执行给定的函数。
你找到的中断向量就是用于此的。你可能想看看它们的64位对应物,在 入口_64.S 并在守卫下 #ifdef CONFIG_SMP
. 该 acpiinterrupt
和 acpiinterrupt3
只是定义了一个标签的宏,第二个参数,调用 interrupt_entry
的第一个参数(向量数)NOTted,然后调用第三个参数中的函数。注意,32位的模拟函数会对目标函数名进行一些讨厌的前缀连词。
apicinterrupt CALL_FUNCTION_SINGLE_VECTOR call_function_single_interrupt smp_call_function_single_interrupt
大致相当于定义函数。
;Metadata stuff (e.g. section placement)
call_function_single_interrupt: ;<-- first arg
push ~CALL_FUNCTION_SINGLE_VECTOR ;<-- second arg
call interrupt_entry
;other stuff (tracing, flags, etc)
call smp_call_function_single_interrupt ;<-- third arg
;other stuff (like above, plus returning)
向量数定义在 irq_vectors.h 当然,也被用于 的IDT.C。 中的IDT.c。
目标函数(中断处理程序)大部分(全部?我没查)定义在 SMP.C 它们可能是最接近ARM的 handle_IPI
处理程序。
这些似乎是唯一通过IPI调用的向量。