0

关于等待队列,我一直在尝试刷新我对在内核中休眠的理解。因此开始浏览bcmgenet.c (内核版本 4.4)的源代码,该驱动程序负责驱动 Broadcom 的 7xxx 系列 SoC 用于他们的机顶盒解决方案。

作为探测回调的一部分,这个驱动程序初始化了一个工作队列,它是驱动程序私有结构的一部分,并将自己添加到 Q 中。但我在任何地方都没有看到任何类型的阻塞。然后它继续使用唤醒时调用的函数初始化工作队列。

现在来到驱动程序的 ISR0,如果满足某些条件,则作为 ISR (bcmgenet_isr0) 的一部分显式调用调度程序。现在 AFAIK,此调用用于将工作推迟到以后,就像 tasklet 一样。

发布此消息后,我们检查一些 MDIO 状态标志,如果满足条件,我们将唤醒在进程上下文中被阻塞的进程。但是这个过程到底是在哪里被阻塞的呢?

此外,大多数时候,等待队列似乎与工作队列一起使用。这是使用它们的典型方式吗?

4

1 回答 1

0

作为探测回调的一部分,这个驱动程序初始化了一个工作队列,它是驱动程序私有结构的一部分,并将自己添加到 Q 中。但我在任何地方都没有看到任何类型的阻塞。

我认为您的意思是等待队列头,而不是工作队列。我没有看到任何证据表明探测器将自身添加到队列中;它只是初始化队列。

该队列由调用bcmmii.cwait_event_timeout()中的bcmgenet_mii_read()bcmgenet_mii_write()函数中的宏使用。这些调用将阻塞,直到它们等待的条件变为真或超时期限过去。它们被ISR0 中断处理程序中的调用唤醒。wake_up(&priv->wq);

然后它继续使用唤醒时调用的函数初始化工作队列。

它正在初始化一个工作项,而不是一个工作队列。由于工作项被添加到系统工作队列中,该函数将从内核线程中调用。

现在来到驱动程序的 ISR0,如果满足某些条件,则作为 ISR (bcmgenet_isr0) 的一部分显式调用调度程序。现在 AFAIK,此调用用于将工作推迟到以后,就像 tasklet 一样。

您指的schedule_work(&priv->bcmgenet_irq_work);是 ISR0 中断处理程序中的调用。这是将前面提到的工作项添加到系统工作队列中。它类似于 tasklet,但 tasklet 在 softirq 上下文中运行,而工作项在进程上下文中运行。

发布此消息后,我们检查一些 MDIO 状态标志,如果满足条件,我们将唤醒在进程上下文中被阻塞的进程。但是这个过程到底是在哪里被阻塞的呢?

如上所述,进程在bcmgenet_mii_read()andbcmgenet_mii_write()函数中被阻塞,尽管它们使用超时来避免长时间阻塞。(这个超时对于那些不支持与 MDIO 相关的中断的 GENET 版本尤其重要!)

此外,大多数时候,等待队列似乎与工作队列一起使用。这是使用它们的典型方式吗?

不是特别。这个特定的驱动程序同时使用了等待队列和工作项,但我不会将它们描述为“结合使用”,因为它们用于处理不同的中断条件。

于 2020-01-06T17:10:44.783 回答