10

在 ULK 的第 5 章中,作者陈述如下:

“......每个中断处理程序都相对于自身进行序列化 - 也就是说,它不能同时执行多个。因此,访问数据结构不需要同步原语”

我不太明白为什么中断处理程序在具有多核的现代 CPU 上被“序列化”。我认为有可能相同的 ISR 可以同时在不同的内核上运行,对吗?如果是这种情况,如果您不使用自旋锁来保护您的数据,它可能会进入竞争状态。

所以我的问题是,在具有多 cpu 的现代系统上,对于您要编写的每个中断处理程序,它将读取和写入一些数据,是否总是需要自旋锁?

4

5 回答 5

7

在执行中断处理程序时,内核在中断控制器上明确禁用该特定中断线,因此一个中断处理程序不能同时执行多次。(不过,其他中断的处理程序可以同时运行。)

于 2013-08-24T22:16:00.883 回答
4

澄清:根据 CL。下面的评论 - 内核确保不会为同一个中断触发中断处理程序,但是如果您为多个中断注册了同一个中断处理程序的多个注册,我相信下面的答案是正确的。

您是对的,同一个中断处理程序可以在多个内核上同时运行,并且共享数据需要受到保护。然而,自旋锁并不是实现这一目标的唯一方式,当然也不总是推荐的方式。

许多其他同步方法,从每个 CPU 数据,仅使用原子操作访问共享数据,甚至读取-复制-更新变体,都可用于保护共享数据。

于 2013-08-25T14:55:12.623 回答
0

中断处理程序中并不总是需要自旋锁。

请首先注意一件事 - 当中断控制器上发生特定设备的中断时,该中断在中断控制器处被禁用,因此在该特定设备的所有内核上。因此,同一设备的中断不能同时出现在所有 CPU 上。因此,在正常情况下,由于代码不会重入,因此不需要任何自旋锁。

尽管在以下两种情况下,中断处理程序中需要自旋锁。

  1. 请注意,当中断来自设备和 IRQ 线时,该内核会禁用该内核上的所有其他中断,也会禁用其他内核上的该设备中断。来自其他设备的中断可能来自其他核心。

因此,可能会为不同的设备注册相同的中断处理程序。例如:- request_irq(A,func,..); reqest_irq(B,func,..); 为设备调用一个中断处理函数。对于设备 B,调用相同的中断处理函数 func。因此,在这种情况下应该使用自旋锁来防止引发条件。

  1. 当在中断处理程序中使用相同的资源以及在进程上下文中运行的其他一些代码时。例如:- 有资源 A 所以可能存在这样一种情况,其中一个内核在中断模式下运行,中断处理程序正在修改资源 A,而其他内核在进程上下文中运行,并且也在其他地方修改相同的资源. 因此,为了呈现该资源的引发条件,我们应该使用自旋锁。
于 2017-01-12T11:32:42.017 回答
0

Marco Cesati 的《Understanding the Linux Kernel, 3rd Edition》第 4.6 节,Daniel P. Bovet告诉了你答案。实际的中断处理程序是由 处理的handle_IRQ_eventirq_desc[irq].lock防止handle_IRQ_event任何其他 CPU 并发访问。

于 2017-11-04T10:02:55.467 回答
-1

如果关键数据是通过中断处理程序和您的进程(可能是内核线程)共享的,那么您需要保护您的数据,因此需要自旋锁。自旋锁的常见内核 api 是:spin_lock()。还有这些 api 的变体,例如 spin_lock_irqsave(),它可以帮助避免在获取/持有自旋锁时可能面临的死锁问题。请通过以下链接查找该主题的详细信息: http://www.linuxjournal .com/article/5833

于 2013-08-25T09:39:41.973 回答