6121 lines · 168.2 KB · C
RawDownload
	if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))		return; 	max_active = wq_clamp_max_active(max_active, wq->flags, wq->name); 	mutex_lock(&wq->mutex); 	wq->flags &= ~__WQ_ORDERED;	wq->saved_max_active = max_active; 	for_each_pwq(pwq, wq)		pwq_adjust_max_active(pwq); 	mutex_unlock(&wq->mutex);}EXPORT_SYMBOL_GPL(workqueue_set_max_active); /** * current_work - retrieve %current task's work struct * * Determine if %current task is a workqueue worker and what it's working on. * Useful to find out the context that the %current task is running in. * * Return: work struct if %current task is a workqueue worker, %NULL otherwise. */struct work_struct *current_work(void){	struct worker *worker = current_wq_worker(); 	return worker ? worker->current_work : NULL;}EXPORT_SYMBOL(current_work); /** * current_is_workqueue_rescuer - is %current workqueue rescuer? * * Determine whether %current is a workqueue rescuer.  Can be used from * work functions to determine whether it's being run off the rescuer task. * * Return: %true if %current is a workqueue rescuer. %false otherwise. */bool current_is_workqueue_rescuer(void){	struct worker *worker = current_wq_worker(); 	return worker && worker->rescue_wq;} /** * workqueue_congested - test whether a workqueue is congested * @cpu: CPU in question * @wq: target workqueue * * Test whether @wq's cpu workqueue for @cpu is congested.  There is * no synchronization around this function and the test result is * unreliable and only useful as advisory hints or for debugging. * * If @cpu is WORK_CPU_UNBOUND, the test is performed on the local CPU. * Note that both per-cpu and unbound workqueues may be associated with * multiple pool_workqueues which have separate congested states.  A * workqueue being congested on one CPU doesn't mean the workqueue is also * contested on other CPUs / NUMA nodes. * * Return: * %true if congested, %false otherwise. */bool workqueue_congested(int cpu, struct workqueue_struct *wq){	struct pool_workqueue *pwq;	bool ret; 	rcu_read_lock();	preempt_disable(); 	if (cpu == WORK_CPU_UNBOUND)		cpu = smp_processor_id(); 	if (!(wq->flags & WQ_UNBOUND))		pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);	else		pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); 	ret = !list_empty(&pwq->inactive_works);	preempt_enable();	rcu_read_unlock(); 	return ret;}EXPORT_SYMBOL_GPL(workqueue_congested); /** * work_busy - test whether a work is currently pending or running * @work: the work to be tested * * Test whether @work is currently pending or running.  There is no * synchronization around this function and the test result is * unreliable and only useful as advisory hints or for debugging. * * Return: * OR'd bitmask of WORK_BUSY_* bits. */unsigned int work_busy(struct work_struct *work){	struct worker_pool *pool;	unsigned long flags;	unsigned int ret = 0; 	if (work_pending(work))		ret |= WORK_BUSY_PENDING; 	rcu_read_lock();	pool = get_work_pool(work);	if (pool) {		raw_spin_lock_irqsave(&pool->lock, flags);		if (find_worker_executing_work(pool, work))			ret |= WORK_BUSY_RUNNING;		raw_spin_unlock_irqrestore(&pool->lock, flags);	}	rcu_read_unlock(); 	return ret;}EXPORT_SYMBOL_GPL(work_busy); /** * set_worker_desc - set description for the current work item * @fmt: printf-style format string * @...: arguments for the format string * * This function can be called by a running work function to describe what * the work item is about.  If the worker task gets dumped, this * information will be printed out together to help debugging.  The * description can be at most WORKER_DESC_LEN including the trailing '\0'. */void set_worker_desc(const char *fmt, ...){	struct worker *worker = current_wq_worker();	va_list args; 	if (worker) {		va_start(args, fmt);		vsnprintf(worker->desc, sizeof(worker->desc), fmt, args);		va_end(args);	}}EXPORT_SYMBOL_GPL(set_worker_desc); /** * print_worker_info - print out worker information and description * @log_lvl: the log level to use when printing * @task: target task * * If @task is a worker and currently executing a work item, print out the * name of the workqueue being serviced and worker description set with * set_worker_desc() by the currently executing work item. * * This function can be safely called on any task as long as the * task_struct itself is accessible.  While safe, this function isn't * synchronized and may print out mixups or garbages of limited length. */void print_worker_info(const char *log_lvl, struct task_struct *task){	work_func_t *fn = NULL;	char name[WQ_NAME_LEN] = { };	char desc[WORKER_DESC_LEN] = { };	struct pool_workqueue *pwq = NULL;	struct workqueue_struct *wq = NULL;	struct worker *worker; 	if (!(task->flags & PF_WQ_WORKER))		return; 	/*	 * This function is called without any synchronization and @task	 * could be in any state.  Be careful with dereferences.	 */	worker = kthread_probe_data(task); 	/*	 * Carefully copy the associated workqueue's workfn, name and desc.	 * Keep the original last '\0' in case the original is garbage.	 */	copy_from_kernel_nofault(&fn, &worker->current_func, sizeof(fn));	copy_from_kernel_nofault(&pwq, &worker->current_pwq, sizeof(pwq));	copy_from_kernel_nofault(&wq, &pwq->wq, sizeof(wq));	copy_from_kernel_nofault(name, wq->name, sizeof(name) - 1);	copy_from_kernel_nofault(desc, worker->desc, sizeof(desc) - 1); 	if (fn || name[0] || desc[0]) {		printk("%sWorkqueue: %s %ps", log_lvl, name, fn);		if (strcmp(name, desc))			pr_cont(" (%s)", desc);		pr_cont("\n");	}} static void pr_cont_pool_info(struct worker_pool *pool){	pr_cont(" cpus=%*pbl", nr_cpumask_bits, pool->attrs->cpumask);	if (pool->node != NUMA_NO_NODE)		pr_cont(" node=%d", pool->node);	pr_cont(" flags=0x%x nice=%d", pool->flags, pool->attrs->nice);} static void pr_cont_work(bool comma, struct work_struct *work){	if (work->func == wq_barrier_func) {		struct wq_barrier *barr; 		barr = container_of(work, struct wq_barrier, work); 		pr_cont("%s BAR(%d)", comma ? "," : "",			task_pid_nr(barr->task));	} else {		pr_cont("%s %ps", comma ? "," : "", work->func);	}} static void show_pwq(struct pool_workqueue *pwq){	struct worker_pool *pool = pwq->pool;	struct work_struct *work;	struct worker *worker;	bool has_in_flight = false, has_pending = false;	int bkt; 	pr_info("  pwq %d:", pool->id);	pr_cont_pool_info(pool); 	pr_cont(" active=%d/%d refcnt=%d%s\n",		pwq->nr_active, pwq->max_active, pwq->refcnt,		!list_empty(&pwq->mayday_node) ? " MAYDAY" : ""); 	hash_for_each(pool->busy_hash, bkt, worker, hentry) {		if (worker->current_pwq == pwq) {			has_in_flight = true;			break;		}	}	if (has_in_flight) {		bool comma = false; 		pr_info("    in-flight:");		hash_for_each(pool->busy_hash, bkt, worker, hentry) {			if (worker->current_pwq != pwq)				continue; 			pr_cont("%s %d%s:%ps", comma ? "," : "",				task_pid_nr(worker->task),				worker->rescue_wq ? "(RESCUER)" : "",				worker->current_func);			list_for_each_entry(work, &worker->scheduled, entry)				pr_cont_work(false, work);			comma = true;		}		pr_cont("\n");	} 	list_for_each_entry(work, &pool->worklist, entry) {		if (get_work_pwq(work) == pwq) {			has_pending = true;			break;		}	}	if (has_pending) {		bool comma = false; 		pr_info("    pending:");		list_for_each_entry(work, &pool->worklist, entry) {			if (get_work_pwq(work) != pwq)				continue; 			pr_cont_work(comma, work);			comma = !(*work_data_bits(work) & WORK_STRUCT_LINKED);		}		pr_cont("\n");	} 	if (!list_empty(&pwq->inactive_works)) {		bool comma = false; 		pr_info("    inactive:");		list_for_each_entry(work, &pwq->inactive_works, entry) {			pr_cont_work(comma, work);			comma = !(*work_data_bits(work) & WORK_STRUCT_LINKED);		}		pr_cont("\n");	}} /** * show_one_workqueue - dump state of specified workqueue * @wq: workqueue whose state will be printed */void show_one_workqueue(struct workqueue_struct *wq){	struct pool_workqueue *pwq;	bool idle = true;	unsigned long flags; 	for_each_pwq(pwq, wq) {		if (pwq->nr_active || !list_empty(&pwq->inactive_works)) {			idle = false;			break;		}	}	if (idle) /* Nothing to print for idle workqueue */		return; 	pr_info("workqueue %s: flags=0x%x\n", wq->name, wq->flags); 	for_each_pwq(pwq, wq) {		raw_spin_lock_irqsave(&pwq->pool->lock, flags);		if (pwq->nr_active || !list_empty(&pwq->inactive_works)) {			/*			 * Defer printing to avoid deadlocks in console			 * drivers that queue work while holding locks			 * also taken in their write paths.			 */			printk_deferred_enter();			show_pwq(pwq);			printk_deferred_exit();		}		raw_spin_unlock_irqrestore(&pwq->pool->lock, flags);		/*		 * We could be printing a lot from atomic context, e.g.		 * sysrq-t -> show_all_workqueues(). Avoid triggering		 * hard lockup.		 */		touch_nmi_watchdog();	} } /** * show_one_worker_pool - dump state of specified worker pool * @pool: worker pool whose state will be printed */static void show_one_worker_pool(struct worker_pool *pool){	struct worker *worker;	bool first = true;	unsigned long flags; 	raw_spin_lock_irqsave(&pool->lock, flags);	if (pool->nr_workers == pool->nr_idle)		goto next_pool;	/*	 * Defer printing to avoid deadlocks in console drivers that	 * queue work while holding locks also taken in their write	 * paths.	 */	printk_deferred_enter();	pr_info("pool %d:", pool->id);	pr_cont_pool_info(pool);	pr_cont(" hung=%us workers=%d",		jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000,		pool->nr_workers);	if (pool->manager)		pr_cont(" manager: %d",			task_pid_nr(pool->manager->task));	list_for_each_entry(worker, &pool->idle_list, entry) {		pr_cont(" %s%d", first ? "idle: " : "",			task_pid_nr(worker->task));		first = false;	}	pr_cont("\n");	printk_deferred_exit();next_pool:	raw_spin_unlock_irqrestore(&pool->lock, flags);	/*	 * We could be printing a lot from atomic context, e.g.	 * sysrq-t -> show_all_workqueues(). Avoid triggering	 * hard lockup.	 */	touch_nmi_watchdog(); } /** * show_all_workqueues - dump workqueue state * * Called from a sysrq handler or try_to_freeze_tasks() and prints out * all busy workqueues and pools. */void show_all_workqueues(void){	struct workqueue_struct *wq;	struct worker_pool *pool;	int pi; 	rcu_read_lock(); 	pr_info("Showing busy workqueues and worker pools:\n"); 	list_for_each_entry_rcu(wq, &workqueues, list)		show_one_workqueue(wq); 	for_each_pool(pool, pi)		show_one_worker_pool(pool); 	rcu_read_unlock();} /* used to show worker information through /proc/PID/{comm,stat,status} */void wq_worker_comm(char *buf, size_t size, struct task_struct *task){	int off; 	/* always show the actual comm */	off = strscpy(buf, task->comm, size);	if (off < 0)		return; 	/* stabilize PF_WQ_WORKER and worker pool association */	mutex_lock(&wq_pool_attach_mutex); 	if (task->flags & PF_WQ_WORKER) {		struct worker *worker = kthread_data(task);		struct worker_pool *pool = worker->pool; 		if (pool) {			raw_spin_lock_irq(&pool->lock);			/*			 * ->desc tracks information (wq name or			 * set_worker_desc()) for the latest execution.  If			 * current, prepend '+', otherwise '-'.			 */			if (worker->desc[0] != '\0') {				if (worker->current_work)					scnprintf(buf + off, size - off, "+%s",						  worker->desc);				else					scnprintf(buf + off, size - off, "-%s",						  worker->desc);			}			raw_spin_unlock_irq(&pool->lock);		}	} 	mutex_unlock(&wq_pool_attach_mutex);} #ifdef CONFIG_SMP /* * CPU hotplug. * * There are two challenges in supporting CPU hotplug.  Firstly, there * are a lot of assumptions on strong associations among work, pwq and * pool which make migrating pending and scheduled works very * difficult to implement without impacting hot paths.  Secondly, * worker pools serve mix of short, long and very long running works making * blocked draining impractical. * * This is solved by allowing the pools to be disassociated from the CPU * running as an unbound one and allowing it to be reattached later if the * cpu comes back online. */ static void unbind_workers(int cpu){	struct worker_pool *pool;	struct worker *worker; 	for_each_cpu_worker_pool(pool, cpu) {		mutex_lock(&wq_pool_attach_mutex);		raw_spin_lock_irq(&pool->lock); 		/*		 * We've blocked all attach/detach operations. Make all workers		 * unbound and set DISASSOCIATED.  Before this, all workers		 * must be on the cpu.  After this, they may become diasporas.		 * And the preemption disabled section in their sched callbacks		 * are guaranteed to see WORKER_UNBOUND since the code here		 * is on the same cpu.		 */		for_each_pool_worker(worker, pool)			worker->flags |= WORKER_UNBOUND; 		pool->flags |= POOL_DISASSOCIATED; 		/*		 * The handling of nr_running in sched callbacks are disabled		 * now.  Zap nr_running.  After this, nr_running stays zero and		 * need_more_worker() and keep_working() are always true as		 * long as the worklist is not empty.  This pool now behaves as		 * an unbound (in terms of concurrency management) pool which		 * are served by workers tied to the pool.		 */		pool->nr_running = 0; 		/*		 * With concurrency management just turned off, a busy		 * worker blocking could lead to lengthy stalls.  Kick off		 * unbound chain execution of currently pending work items.		 */		wake_up_worker(pool); 		raw_spin_unlock_irq(&pool->lock);

Lines 4501–5000 of 6121. Previous lines