c - tasklet_action()函数中为什么会调用BUG?

标签 c linux-kernel

static void tasklet_action(struct softirq_action *a)
{
    // ...

    while (list) {
        struct tasklet_struct *t = list;

        list = list->next;

        if (tasklet_trylock(t)) {
            if (!atomic_read(&t->count)) {
                if (!test_and_clear_bit(TASKLET_STATE_SCHED,
                            &t->state))
                    BUG();

                // ...
    }
}
我的理解是,如果已经安排了一个 tasklet,那么这段代码会抛出 BUG() .
这是否意味着同一个 tasklet 不能同时运行,也不能被调度?

最佳答案

这只是对 tasklets 的保证属性的完整性检查。您可以看到 a comment in include/linux/interrupt.h 中列出的 tasklet 的属性:

   Properties:
   * If tasklet_schedule() is called, then tasklet is guaranteed
     to be executed on some cpu at least once after this.
   * If the tasklet is already scheduled, but its execution is still not
     started, it will be executed only once.
   * If this tasklet is already running on another CPU (or schedule is called
     from tasklet itself), it is rescheduled for later.
   * Tasklet is strictly serialized wrt itself, but not
     wrt another tasklets. If client needs some intertask synchronization,
     he makes it with spinlocks.
根据定义,tasklet 保证在被调度后至少运行一次。这段代码:
    if (!atomic_read(&t->count)) {
        if (!test_and_clear_bit(TASKLET_STATE_SCHED,
                    &t->state))
            BUG();
确保这个属性成立,否则有一个bug,和BUG()用于停止执行并导致运行时 panic 。
这是上述代码的注释版本,以使其更清晰:
    // If the tasklet never ran (t->count == 0)
    if (!atomic_read(&t->count)) {
        // And the tasklet is not scheduled for running (bit TASKLET_STATE_SCHED of t->state is 0)
        if (!test_and_clear_bit(TASKLET_STATE_SCHED,
                    &t->state))
            // There's something wrong, this should never happen!
            BUG();
换句话说,你不能有一个带有 t->count == 0 的 tasklet。和 t->state & (1<<TASKLET_STATE_SCHED) == 0 .如果发生这种情况,则存在错误。

关于c - tasklet_action()函数中为什么会调用BUG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67246357/

相关文章:

c++ - 在 C++ 中绑定(bind) C 函数( undefined reference )

c - 在 Linux 中使用文件时,哪些内核模块负责?

linux - 关闭,比如 vim,会触发 sys_exit 吗?

在 LINUX 中检查简单的字符设备读/写函数

c - readline.h 不在 32 位 ubuntu 中,而是在 64 位中?

c++ - 运算符 < 和 > 如何与指针一起使用?

代码适用于 MinGW,但不适用于我大学的计算机(C 语言)

c - 使用堆栈或 atoi() 时出现运行时错误

linux - 从头开始创建简单的微型 ELF

c - 两次向 Linux 内核双链表添加元素