等待队列和工作队列,它们总是在一起吗?

wait queues and work queues, do they always go together?

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

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

现在进入驱动程序的 ISR0,如果满足某些条件,其中有一个 explicit call to the scheduler 作为 ISR (bcmgenet_isr0) 的一部分。现在 AFAIK,此调用用于将工作推迟到以后的时间,就像 tasklet 一样。

Post 我们检查一些 MDIO 状态标志,如果满足条件,我们唤醒在进程上下文中被阻塞的进程。 但是进程到底阻塞在什么地方?

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

As part of the probe callback, this driver initializes a work queue which is part of the driver’s private structure and adds itself to the Q. But I do not see any blocking of any kind anywhere.

我想你指的是等待队列头,而不是工作队列。我没有看到探测器将自己添加到队列中的任何证据;它只是在初始化队列。

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

Then it goes on to initialize a work queue with a function to call when woken up.

正在初始化工作项,而不是工作队列。作为将工作项添加到系统工作队列的结果,将从内核线程调用该函数。

Now coming to the ISR0 for the driver, within that is an explicit call to the scheduler as part of the ISR (bcmgenet_isr0) if certain conditions are met. Now AFAIK, this call is used to defer work to a later time, much like a tasklet does.

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

Post this we check some MDIO status flags and if the conditions are met, we wake up the process which was blocked in process context. But where exactly is the process blocked?

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

Also, most of the time, wait queues seem to be used in conjunction with work queues. Is that the typical way to use them?

不是特别喜欢。这个特定的驱动程序同时使用等待队列和工作项,但我不会将它们描述为正在使用 "in conjunction",因为它们被用于处理不同的中断条件。