等待队列和工作队列,它们是否总是一起使用?

huangapple go评论95阅读模式
英文:

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

问题

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

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

现在来看驱动程序的ISR0,在其中,如果满足某些条件,作为ISR的一部分会显式调用调度程序。就我所知,此调用用于将工作推迟到以后的时间,就像任务let一样。

之后,我们检查一些MDIO状态标志,如果满足条件,我们唤醒了在进程上下文中被阻塞的进程。但进程到底在哪里被阻塞?

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

英文:

I’ve been trying to refresh my understanding of sleeping in the kernel with regards to wait queues. So started browsing the source code for bcmgenet.c (kernel version 4.4) which is the driver responsible for driving the 7xxx series of Broadcom SoC for their set top box solution.

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. 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.

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?

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

答案1

得分: 0

  • 作为探针回调的一部分,该驱动程序初始化了一个工作队列,该队列是驱动程序的私有结构的一部分,并将自身添加到队列中。但我没有看到任何地方有任何形式的阻塞。

  • 我认为你指的是等待队列头,而不是工作队列。我没有看到任何证据表明探针将自己添加到队列中;它只是初始化了队列。

  • 这个队列被用于bcmgenet_mii_read()bcmgenet_mii_write()函数中的wait_event_timeout()宏调用中。这些调用将阻塞,直到它们等待的条件变为真或超时期限到期为止。它们会被ISR0中的wake_up(&priv->wq);调用唤醒。

  • 然后它继续初始化一个工作项,并在唤醒时调用一个函数。

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

  • 现在来看驱动程序的ISR0,在其中如果满足某些条件,会有一个显式调用调度器的操作(bcmgenet_isr0)。据我所知,此调用用于推迟工作到以后的时间,就像任务队列一样。

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

  • 之后,我们检查一些MDIO状态标志,如果满足条件,就会唤醒在进程上下文中被阻塞的进程。但进程究竟在哪里被阻塞呢?

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

  • 此外,大多数情况下,等待队列似乎与工作队列一起使用。这是典型的用法吗?

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

英文:

> 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.

I think you meant the wait queue head, not the work queue. I do not see any evidence of the probe adding itself to the queue; it is merely initializing the queue.

The queue is used by the calls to the wait_event_timeout() macro in the bcmgenet_mii_read() and bcmgenet_mii_write() functions in bcmmii.c. These calls will block until either the condition they are waiting for becomes true or the timeout period elapses. They are woken up by the wake_up(&priv->wq); call in the ISR0 interrupt handler.

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

It is initializing a work item, not a work queue. The function will be called from a kernel thread as a result of the work item being added to the system work queue.

> 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.

You are referring to the schedule_work(&priv->bcmgenet_irq_work); call in the ISR0 interrupt handler. This is adding the previously mentioned work item to the system work queue. It is similar to as tasklet, but tasklets are run in a softirq context whereas work items are run in a process context.

> 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?

As mentioned above, the process is blocked in the bcmgenet_mii_read() and bcmgenet_mii_write() functions, although they use a timeout to avoid blocking for long periods. (This timeout is especially important for those versions of GENET that do not support MDIO-related interrupts!)

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

Not especially. This particular driver uses both a wait queue and a work item, but I wouldn't describe them as being used "in conjunction" since they are being used to handle different interrupt conditions.

huangapple
  • 本文由 发表于 2020年1月3日 14:25:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/59574083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定