6121 lines · 168.2 KB · C
RawDownload
	/* initialize CPU pools */	for_each_possible_cpu(cpu) {		struct worker_pool *pool; 		i = 0;		for_each_cpu_worker_pool(pool, cpu) {			BUG_ON(init_worker_pool(pool));			pool->cpu = cpu;			cpumask_copy(pool->attrs->cpumask, cpumask_of(cpu));			pool->attrs->nice = std_nice[i++];			pool->node = cpu_to_node(cpu); 			/* alloc pool ID */			mutex_lock(&wq_pool_mutex);			BUG_ON(worker_pool_assign_id(pool));			mutex_unlock(&wq_pool_mutex);		}	} 	/* create default unbound and ordered wq attrs */	for (i = 0; i < NR_STD_WORKER_POOLS; i++) {		struct workqueue_attrs *attrs; 		BUG_ON(!(attrs = alloc_workqueue_attrs()));		attrs->nice = std_nice[i];		unbound_std_wq_attrs[i] = attrs; 		/*		 * An ordered wq should have only one pwq as ordering is		 * guaranteed by max_active which is enforced by pwqs.		 * Turn off NUMA so that dfl_pwq is used for all nodes.		 */		BUG_ON(!(attrs = alloc_workqueue_attrs()));		attrs->nice = std_nice[i];		attrs->no_numa = true;		ordered_wq_attrs[i] = attrs;	} 	system_wq = alloc_workqueue("events", 0, 0);	system_highpri_wq = alloc_workqueue("events_highpri", WQ_HIGHPRI, 0);	system_long_wq = alloc_workqueue("events_long", 0, 0);	system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,					    WQ_UNBOUND_MAX_ACTIVE);	system_freezable_wq = alloc_workqueue("events_freezable",					      WQ_FREEZABLE, 0);	system_power_efficient_wq = alloc_workqueue("events_power_efficient",					      WQ_POWER_EFFICIENT, 0);	system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient",					      WQ_FREEZABLE | WQ_POWER_EFFICIENT,					      0);	BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||	       !system_unbound_wq || !system_freezable_wq ||	       !system_power_efficient_wq ||	       !system_freezable_power_efficient_wq);} /** * workqueue_init - bring workqueue subsystem fully online * * This is the latter half of two-staged workqueue subsystem initialization * and invoked as soon as kthreads can be created and scheduled. * Workqueues have been created and work items queued on them, but there * are no kworkers executing the work items yet.  Populate the worker pools * with the initial workers and enable future kworker creations. */void __init workqueue_init(void){	struct workqueue_struct *wq;	struct worker_pool *pool;	int cpu, bkt; 	/*	 * It'd be simpler to initialize NUMA in workqueue_init_early() but	 * CPU to node mapping may not be available that early on some	 * archs such as power and arm64.  As per-cpu pools created	 * previously could be missing node hint and unbound pools NUMA	 * affinity, fix them up.	 *	 * Also, while iterating workqueues, create rescuers if requested.	 */	wq_numa_init(); 	mutex_lock(&wq_pool_mutex); 	for_each_possible_cpu(cpu) {		for_each_cpu_worker_pool(pool, cpu) {			pool->node = cpu_to_node(cpu);		}	} 	list_for_each_entry(wq, &workqueues, list) {		wq_update_unbound_numa(wq, smp_processor_id(), true);		WARN(init_rescuer(wq),		     "workqueue: failed to create early rescuer for %s",		     wq->name);	} 	mutex_unlock(&wq_pool_mutex); 	/* create the initial workers */	for_each_online_cpu(cpu) {		for_each_cpu_worker_pool(pool, cpu) {			pool->flags &= ~POOL_DISASSOCIATED;			BUG_ON(!create_worker(pool));		}	} 	hash_for_each(unbound_pool_hash, bkt, pool, hash_node)		BUG_ON(!create_worker(pool)); 	wq_online = true;	wq_watchdog_init();} /* * Despite the naming, this is a no-op function which is here only for avoiding * link error. Since compile-time warning may fail to catch, we will need to * emit run-time warning from __flush_workqueue(). */void __warn_flushing_systemwide_wq(void) { }EXPORT_SYMBOL(__warn_flushing_systemwide_wq);

Lines 6001–6121 of 6121. Previous lines