0x0*_*7FC 3 c scheduled-tasks linux-kernel interrupt-handling workqueue
在研究工作队列时,我遇到了内核中定义的工作队列标志和常量。我有以下疑问,我无法理解。
排水和救援人员在这里到底是什么意思?
WQ_DRAINING = 1 << 6, /* internal: workqueue is draining */
WQ_RESCUER = 1 << 7, /* internal: workqueue has rescuer */
Run Code Online (Sandbox Code Playgroud)为未绑定工作队列定义的 CPU 数量是 4。如果我有一个八核处理器会怎样。无界 wq 将如何绑定到 cpus。他们如何决定运行哪些 CPU,因为他们现在有 8 个 cpu 而不是 4 个 cpu。是这样,它们可以在 8 个或仅 4 个特定 cpu 中的任何一个上运行吗?
WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */
此标志用于指示内核当前正在刷新工作队列并且新的工作项不能在其上排队。在此阶段只允许当前挂起或正在运行的工作项,直到整个工作队列完全清空为止。
有关详细信息,请查看drain_workqueue()in的实现kernel/workqueue.c。
此补丁已在最新内核中弃用此标志,现在行为由该WQ_MEM_RECLAIM标志决定。
就“救援”功能而言,这里是文档的相关部分kernel/workqueue.c,
工作队列救援线程函数。每个设置了 WQ_MEM_RECLAIM 的工作队列都有一个救援者。
池上的常规工作处理可能会阻止尝试创建使用 GFP_KERNEL 分配的新工作线程,如果需要处理当前在同一队列上的某些工作以满足 GFP_KERNEL 分配,则极有可能发展为死锁。这是救援人员解决的问题。
当这种情况可能发生时,池会召集所有在池中排队的工作队列的救援人员,让他们处理这些工作,以保证前进的进度。
(与您的解释相反,WQ_MAX_UNBOUND_PER_CPU不是 CPU 的数量。它是可以与 CPU 关联的工作队列的数量。)
工作队列传统上是每个 CPU 的,即每个工作队列都与一个特定的 CPU 相关联,由于缓存局部性导致更好的性能。内核调度程序别无选择,只能在定义它的 cpu 上调度它。在当前架构中,这会导致功耗增加,因为即使是单个工作队列也可以防止 CPU 空闲和关闭。因此引入了未绑定的工作队列。调度程序可以自由地在任何 cpu 上重新调度未绑定的工作队列,因为它认为合适。
此类工作队列的总数WQ_UNBOUND_MAX_ACTIVE被定义为num_possible_cpus() * WQ_MAX_UNBOUND_PER_CPU(最多由 确定的系统中总工作队列的限制WQ_MAX_ACTIVE)。