疑问1:继续Queue同一个work能成功加入worker_pool->worklist吗?
/** * queue_work_on - queue work on specific cpu * @cpu: CPU number to execute work on * @wq: workqueue to use * @work: work to queue * * We queue the work to a specific CPU, the caller must ensure it * can't go away. Callers that fail to ensure that the specified * CPU cannot go away will execute on a randomly chosen CPU. * * Return: %false if @work was already on a queue, %true otherwise. */ bool queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work) { bool ret = false; unsigned long flags; local_irq_save(flags);//关闭本地中断,防止work的data并发设置 if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { __queue_work(cpu, wq, work);//WORK_STRUCT_PENDING_BIT表示任务已经在处理了,完成之前不能重复提交。 ret = true; } local_irq_restore(flags);//打开本地中断 return ret; } EXPORT_SYMBOL(queue_work_on);
疑问2:假设pwq->nr_active >= max_active 时;还能继续insert work成功吗?
1425 static void __queue_work(int cpu, struct workqueue_struct *wq, 1426 struct work_struct *work) 1427 { 1428 struct pool_workqueue *pwq; 1429 struct worker_pool *last_pool; 1430 struct list_head *worklist; 1431 unsigned int work_flags; 1432 unsigned int req_cpu = cpu; 1433 1434 /* 1435 * While a work item is PENDING && off queue, a task trying to 1436 * steal the PENDING will busy-loop waiting for it to either get 1437 * queued or lose PENDING. Grabbing PENDING and queueing should 1438 * happen with IRQ disabled. 1439 */ 1440 lockdep_assert_irqs_disabled();
…… ……
1503 /* pwq determined, queue */ 1504 trace_workqueue_queue_work(req_cpu, pwq, work); 1505 1506 if (WARN_ON(!list_empty(&work->entry))) 1507 goto out; 1508 1509 pwq->nr_in_flight[pwq->work_color]++; 1510 work_flags = work_color_to_flags(pwq->work_color); 1511 1512 if (likely(pwq->nr_active < pwq->max_active)) { 1513 trace_workqueue_activate_work(work); 1514 pwq->nr_active++; 1515 worklist = &pwq->pool->worklist; 1516 if (list_empty(worklist)) 1517 pwq->pool->watchdog_ts = jiffies; 1518 } else { 1519 work_flags |= WORK_STRUCT_INACTIVE; 1520 worklist = &pwq->inactive_works; 1521 } 1522 1523 debug_work_activate(work); 1524 insert_work(pwq, work, worklist, work_flags); 1525 1526 out: 1527 raw_spin_unlock(&pwq->pool->lock); 1528 rcu_read_unlock(); 1529 }2
文章讨论了在特定CPU上将工作加入工作队列(queue_work_on)的方法,以及当工作队列活跃任务数接近最大值时如何处理新工作的插入。它涉及工作结构的工作状态管理和线程池的容量控制。
1713





