同步对设备数据的访问

通常,驱动程序的 InterruptServiceInterruptMessageService 例程 (ISR) 必须与其他驱动程序例程共享对驱动程序数据和硬件资源的访问权限。 由于 ISR 在提升的 IRQL 的中断上下文中执行,并且系统可能有多个处理器,因此同步对共享数据和资源的访问非常重要,以便可以保证每个例程暂时具有对此共享信息的独占访问权限,而不会中断。

系统通过执行中断关键节中的 ISR 支持 此同步。 中断具有分配的旋转锁、中断 旋转锁和 IRQL, 即中断同步 IRQL。 系统通过向中断同步 IRQL 引发处理器的 IRQL,并执行代码之前获取中断旋转锁,保证此代码在关键节中以独占方式访问共享信息。 系统在执行其 ISR 之前始终进入中断的关键部分。 不同的中断可以通过共享中断旋转锁和同步 IRQL 来共享同一个关键部分。

驱动程序可以通过提供 SynchCritSection 例程来实现在中断的关键部分中运行的代码。 当驱动程序使用 KeSynchronizeExecution 调用 SynchCritSection 例程时,系统会自动进入 Interrupt 参数指定的中断的关键部分。

将处理器的 IRQL 提升为中断的同步 IRQL 可防止当前处理器被中断,但具有更高同步 IRQL 的中断除外。 获取旋转锁可防止其他处理器执行与该旋转锁关联的任何关键节代码。

当驱动程序调用 IoConnectInterruptEx 时,系统会为中断分配中断旋转锁和同步 IRQL。 在大多数情况下,驱动程序可以允许系统确定这两个值:

  • 如果驱动程序使用 ioConnectInterruptEx CONNECT_LINE_BASED版本并指定 NULL 旋转锁,系统将为中断行分配旋转锁。 系统还确定同步 IRQL 的值 (驱动程序可以选择性地指定更高的值) 。

  • 如果驱动程序使用 ioConnectInterruptEx CONNECT_MESSAGE_BASED版本并指定 NULL 旋转锁,系统将为每条中断消息分配一个旋转锁。 系统还确定每个消息的同步 IRQL 值 (驱动程序可以选择指定一个更高的值,该值将是所有消息) 。

只有在使用 IoConnectInterruptEx CONNECT_FULLY_SPECIFIED且具有多个必须共享同一关键节的中断向量时,驱动程序才能分配自己的旋转锁。 驱动程序可以使用自签名的 SpinLockSynchronizeIrql 成员来指定自己的旋转锁和同步 IRQL IO_CONNECT_INTERRUPT_PARAMETERS。 有关详细信息,请参阅 IO_CONNECT_INTERRUPT_PARAMETERS。

有关编写和输入关键部分的信息,请参阅 使用关键部分