为什么同一个TASKLET不能同时在两个内核上执行?

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

  • 现在从ISR执行返回时,它将处理softirq和tasklets中的延期工作。
  • 现在这个延迟工作可以在IRQ启用的中断上下文中处理,或者有可以在进程上下文中处理它的ksoftirq线程。
  • 相同的tasklet将在ksoftirq线程为percpu的同一CPU上执行。
  • 在很多书中我都看到,例如LDD,Robert Love的书,它声称同一个tasklet不能同时在两个内核上执行?
  • 怎么样? 有人可以帮助我...如果是这样,我错过了什么?


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

    原因是我相信简化开发模型:使其更容易实现本质上是中断处理程序的内容,而无需担心由于在多个处理器上同时执行而导致的竞争 - 并且不会禁用其他中断。 (很明显,驾驶员开发人员需要了解的其他比赛机会还很多,但这些都是最难解决的问题。)

    如果你问的是实现,其实很简单。 在tasklet_action ,调用tasklet_trylock 。 它使用保证原子函数test_and_set_bit来设置TASKLET_STATE_RUN位。 这只能在一个处理器上成功。 因此,所有其他处理器都会被禁止执行该tasklet,直到该位被清除 - 这只能由在tasklet完成后设置它的处理器完成。

    编辑:
    说明:在任意数量的CPU上调用tasklet_schedule (在执行之前)会导致tasklet执行一次:在第一个进行调用的CPU上。 同样的机制( test_and_set_bit )确保如果tasklet已经在其他某个CPU上被调度过但尚未执行,它将不会被添加到后面的C​​PU上的tasklets-to-run队列中(因此不会被在后面的CPU上执行)。

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


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

    一个函数指针数组被维护。 当softirq被注册时,一个有效的函数指针被写入适当的索引。 索引代表softirq的编号,0是最高优先级softirq。 一个字作为未决softirq的掩码来维护。

    当sofirqs被提升时,掩码中的相应位被设置,当前9个softirqs的数量由一个字的每一位表示。接下来,当内核想要运行待处理的softirqs时,它使用掩码字来标识待处理的softirqs,函数调用是使用数组的第0个索引映射到掩码字的第0位来调用的。

    Tasklet通过softirqs实现,数组的索引0和索引5包含指向分别处理高和正常小任务的函数的指针。 Tasklet使用包含函数指针和其他成员中的状态标志的结构来标识。

    无论何时创建tasklet,都会创建一个结构,并使用实现该tasklet的函数的地址填充函数指针。 维护所有这些结构的链接列表。 当tasklet被调度时,它(内核)将相应的结构添加到链接列表的头部并提升tasklet的softirq,即在掩码字中设置相应的位。

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

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

    链接地址: http://www.djcxy.com/p/84803.html

    上一篇: why same TASKLET can't execute on two core simultaneously?

    下一篇: Exactly when tasklet runs after it is schedule by ISR?