0

在 ARM 平台的 linux 内核实现中,tasklet 中的延迟工作被添加到 percpu vec|vec_hi 列表中。

  1. 现在,当从 ISR 执行返回时,它会处理 softirq 和 tasklet 中的延迟工作。
  2. 现在可以在启用 IRQ 的中断上下文中处理此延迟工作,或者有可以在进程上下文中处理它的 ksoftirq 线程。
  3. 相同的 tasklet 将在相同的 CPU 上执行,因为 ksoftirq 线程是 percpu。
  4. 我一直在很多书中看到,例如LDD,Robert Love的书,它声称不能同时在两个核心上执行同一个tasklet?

如何?有人可以帮我解决这个问题...如果是这样,我错过了什么?

4

2 回答 2

2

这是真的。虽然可以在任意数量的 CPU 上调度 tasklet(即请求执行 tasklet),但它只会在一个 CPU 上执行。

这样做的原因是我相信简化开发模型:更容易实现本质上是一个中断处理程序,而无需担心由于在多个处理器上同时执行而导致的竞争——同时不禁用其他中断。(显然,车手开发人员还需要注意许多其他比赛机会,但这些都是最难解决的。)

如果您要询问实现,它实际上非常简单。在tasklet_actiontasklet_trylock被称为。它使用保证原子功能test_and_set_bit来设置TASKLET_STATE_RUN位。这只能在一个处理器上成功。因此,在该位被清除之前,所有其他处理器都无法执行 tasklet——这仅由在 tasklet 完成后设置它的处理器完成。

编辑:
澄清:调用tasklet_schedule任意数量的 CPU(在执行之前)会导致 tasklet 只执行一次:在第一个调用的 CPU 上。test_and_set_bit同样机制(完全在后来的 CPU 上)。

另一方面,如果它已经开始在第一个 CPU 上执行,该TASKLET_STATE_SCHEDULE位将被清除(因此可能会再次设置),因此另一个调用tasklet_schedule确保 tasklet 最终将在后面的 CPU 上重新执行,但要等到它在第一个 CPU 上运行完成之后。

于 2015-10-15T11:26:58.753 回答
1

softirqs 是下半部中断处理,基于索引的函数调用机制,其中函数实现了 softirq 的功能。

维护了一个函数指针数组。当一个软中断被注册时,一个有效的函数指针被写入到适当的索引中。索引表示softirq的数量,0为最高优先级的softirq。保留一个单词作为挂起的软中断的掩码。

当前 9 个软中断的数量由一个字的每个位表示,当提高软中断时,设置掩码中的相应位。接下来,当内核想要运行挂起的软中断时,它使用掩码的字来识别挂起的软中断,并适当函数调用是使用数组调用的,数组的第 0 个索引映射到掩码字的第 0 位。

Tasklet 是在 softirqs 上实现的,数组的索引 0 和索引 5 包含指向分别处理高和普通小任务的函数的指针。Tasklet 由一个结构标识,该结构在其他成员中包含一个函数指针和一个状态标志。

每当创建 tasklet 时,都会创建一个结构,用实现 tasklet 的函数的地址填充函数指针。维护所有此类结构的链接列表。当 tasklet 被调度时,它(内核)将相应的结构添加到链表的头部并提高 tasklet 的软中断,即在掩码字中设置适当的位。

接下来,当调用处理小任务的函数时,它检查链接列表的所有元素,并在状态标志未运行的情况下调用结构中的函数,这表明它已经在处理器中运行。

因此内核确保没有 2 个相同的小任务在多个处理器中运行。

于 2015-10-16T18:36:34.403 回答