参考
讲解Linux内核工作队列workqueue源码分析 - 知乎
浅谈Linux内核中断下半部——工作队列(work queue) - 知乎
kernel/workqueue.c
初始化
/** 6004 * workqueue_init_early - early init for workqueue subsystem 6005 * 6006 * This is the first half of two-staged workqueue subsystem initialization 6007 * and invoked as soon as the bare basics - memory allocation, cpumasks and 6008 * idr are up. It sets up all the data structures and system workqueues 6009 * and allows early boot code to create workqueues and queue/cancel work 6010 * items. Actual work item execution starts only after kthreads can be 6011 * created and scheduled right before early initcalls. 6012 */ 6013 void __init workqueue_init_early(void) 6014 { 6015 int std_nice[NR_STD_WORKER_POOLS] = { 0, HIGHPRI_NICE_LEVEL }; 6016 int hk_flags = HK_FLAG_DOMAIN | HK_FLAG_WQ; 6017 int i, cpu; 6018 6019 BUILD_BUG_ON(__alignof__(struct pool_workqueue) < __alignof__(long long)); 6020 6021 BUG_ON(!alloc_cpumask_var(&wq_unbound_cpumask, GFP_KERNEL)); 6022 cpumask_copy(wq_unbound_cpumask, housekeeping_cpumask(hk_flags)); 6023 6024 pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC); 6025 6026 /* initialize CPU pools */ 6027 for_each_possible_cpu(cpu) { 6028 struct worker_pool *pool; 6029 6030 i = 0; 6031 for_each_cpu_worker_pool(pool, cpu) { 6032 BUG_ON(init_worker_pool(pool)); 6033 pool->cpu = cpu; 6034 cpumask_copy(pool->attrs->cpumask, cpumask_of(cpu)); 6035 pool->attrs->nice = std_nice[i++]; 6036 pool->node = cpu_to_node(cpu); 6037 6038 /* alloc pool ID */ 6039 mutex_lock(&wq_pool_mutex); 6040 BUG_ON(worker_pool_assign_id(pool)); 6041 mutex_unlock(&wq_pool_mutex); 6042 } 6043 } 6044 6045 /* create default unbound and ordered wq attrs */ 6046 for (i = 0; i < NR_STD_WORKER_POOLS; i++) { 6047 struct workqueue_attrs *attrs; 6048 6049 BUG_ON(!(attrs = alloc_workqueue_attrs())); 6050 attrs->nice = std_nice[i]; 6051 unbound_std_wq_attrs[i] = attrs; 6052 6053 /* 6054 * An ordered wq should have only one pwq as ordering is 6055 * guaranteed by max_active which is enforced by pwqs. 6056 * Turn off NUMA so that dfl_pwq is used for all nodes. 6057 */ 6058 BUG_ON(!(attrs = alloc_workqueue_attrs())); 6059 attrs->nice = std_nice[i]; 6060 attrs->no_numa = true; 6061 ordered_wq_attrs[i] = attrs; 6062 } 6063 6064 system_wq = alloc_workqueue("events", 0, 0); 6065 system_highpri_wq = alloc_workqueue("events_highpri", WQ_HIGHPRI, 0); 6066 system_long_wq = alloc_workqueue("events_long", 0, 0); 6067 system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, 6068 WQ_UNBOUND_MAX_ACTIVE); 6069 system_freezable_wq = alloc_workqueue("events_freezable", 6070 WQ_FREEZABLE, 0); 6071 system_power_efficient_wq = alloc_workqueue("events_power_efficient", 6072 WQ_POWER_EFFICIENT, 0); 6073 system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient", 6074 WQ_FREEZABLE | WQ_POWER_EFFICIENT, 6075 0); 6076 BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq || 6077 !system_unbound_wq || !system_freezable_wq || 6078 !system_power_efficient_wq || 6079 !system_freezable_power_efficient_wq); 6080 }
创建内核work 线程