aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index f128b3becfe1..8ad214dc15a9 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2091,7 +2091,7 @@ __acquires(&pool->lock)
2091 2091
2092 spin_unlock_irq(&pool->lock); 2092 spin_unlock_irq(&pool->lock);
2093 2093
2094 lock_map_acquire_read(&pwq->wq->lockdep_map); 2094 lock_map_acquire(&pwq->wq->lockdep_map);
2095 lock_map_acquire(&lockdep_map); 2095 lock_map_acquire(&lockdep_map);
2096 crossrelease_hist_start(XHLOCK_PROC); 2096 crossrelease_hist_start(XHLOCK_PROC);
2097 trace_workqueue_execute_start(work); 2097 trace_workqueue_execute_start(work);
@@ -2826,16 +2826,18 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
2826 spin_unlock_irq(&pool->lock); 2826 spin_unlock_irq(&pool->lock);
2827 2827
2828 /* 2828 /*
2829 * If @max_active is 1 or rescuer is in use, flushing another work 2829 * Force a lock recursion deadlock when using flush_work() inside a
2830 * item on the same workqueue may lead to deadlock. Make sure the 2830 * single-threaded or rescuer equipped workqueue.
2831 * flusher is not running on the same workqueue by verifying write 2831 *
2832 * access. 2832 * For single threaded workqueues the deadlock happens when the work
2833 * is after the work issuing the flush_work(). For rescuer equipped
2834 * workqueues the deadlock happens when the rescuer stalls, blocking
2835 * forward progress.
2833 */ 2836 */
2834 if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) 2837 if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) {
2835 lock_map_acquire(&pwq->wq->lockdep_map); 2838 lock_map_acquire(&pwq->wq->lockdep_map);
2836 else 2839 lock_map_release(&pwq->wq->lockdep_map);
2837 lock_map_acquire_read(&pwq->wq->lockdep_map); 2840 }
2838 lock_map_release(&pwq->wq->lockdep_map);
2839 2841
2840 return true; 2842 return true;
2841already_gone: 2843already_gone: