Commit 0a5d6c64 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-5.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

Pull workqueue fixes from Tejun Heo:
 "One patch to add a missing __printf annotation and the other to enable
  deferred printing for debug dumps to avoid deadlocks when triggered
  from some contexts (e.g. console drivers)"

* 'for-5.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
  workqueue: fix state-dump console deadlock
  workqueue: annotate alloc_workqueue() as printf
parents 1986c10a 57116ce1
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -399,9 +399,8 @@ extern struct workqueue_struct *system_freezable_power_efficient_wq;
 * RETURNS:
 * Pointer to the allocated workqueue on success, %NULL on failure.
 */
struct workqueue_struct *alloc_workqueue(const char *fmt,
					 unsigned int flags,
					 int max_active, ...);
__printf(1, 4) struct workqueue_struct *
alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...);

/**
 * alloc_ordered_workqueue - allocate an ordered workqueue
+16 −2
Original line number Diff line number Diff line
@@ -4830,8 +4830,16 @@ void show_workqueue_state(void)

		for_each_pwq(pwq, wq) {
			raw_spin_lock_irqsave(&pwq->pool->lock, flags);
			if (pwq->nr_active || !list_empty(&pwq->inactive_works))
			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.
@@ -4849,7 +4857,12 @@ void show_workqueue_state(void)
		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",
@@ -4864,6 +4877,7 @@ void show_workqueue_state(void)
			first = false;
		}
		pr_cont("\n");
		printk_deferred_exit();
	next_pool:
		raw_spin_unlock_irqrestore(&pool->lock, flags);
		/*