产生这种数据完整性问题的原因是INTx这个异步信号。
这里也再次提醒系统程序员注意PCI总线的“异步”中断所带来的数据完整性问题。在一个操作系统中,即便中断处理程序没有首先读取PCI设备的寄存器,也多半不会出现问题,因为在操作系统中,一个PCI设备从提交中断到处理器开始执行设备的中断服务例程,所需要的时间较长,处理器系统基本上可以保证此时数据已经写入存储器。
但是如果系统程序员不这样做,这个驱动程序依然有Bug存在,尽管这个Bug因为各种机缘巧合,始终不能够暴露出来,而一旦这些Bug被暴露出来将难以定位。为此系统程序员务必要重视设计中出现的每一个实现细节,当然仅凭谨慎小心是远远不够的,因为重视细节的前提是充分理解这些细节。
PCI总线V2.2规范还定义了一种新的中断机制,即MSI中断机制。MSI中断机制采用存储器写总线事务向处理器系统提交中断请求,其实现机制是向HOST处理器指定的一个存储器地址写指定的数据。这个存储器地址一般是中断控制器规定的某段存储器地址范围,而且数据也是事先安排好的数据,通常含有中断向量号。
HOST主桥会将MSI这个特殊的存储器写总线事务进一步翻译为中断请求,提交给处理器。目前PCIe和PCI-X设备必须支持MSI中断机制,但是PCI设备并不一定都支持MSI中断机制。
目前MSI中断机制虽然在PCIe总线上已经成为主流,但是在PCI设备中并不常用。即便是支持MSI中断机制的PCI设备,在设备驱动程序的实现中也很少使用这种机制。首先PCI设备具有INTx#信号可以传递中断,而且这种中断传送方式在PCI总线中根深蒂固。其次PCI总线是一个共享总线,传递MSI中断需要占用PCI总线的带宽,需要进行总线仲裁等一系列过程,远没有使用INTx#信号线直接。
但是使用MSI中断机制可以取消PCI总线这个INTx#边带信号,可以解决使用INTx中断机制所带来的数据完整性问题。而更为重要的是,PCI设备使用MSI中断机制,向处理器系统提交中断请求的同时,还可以通知处理器系统产生该中断的原因,即通过不同中断向量号表示中断请求的来源。当处理器系统执行中断服务例程时,不需要读取PCI设备的中断状态寄存器,获得中断请求的来源,从而在一定程度上提高了中断处理的效率。本书将在第8章详细介绍MSI中断机制。
|