Skip to content

Commit 2717b5e

Browse files
Xuewen Yangregkh
authored andcommitted
workqueue: Add rcu lock check at the end of work item execution
[ Upstream commit 1a65a6d ] Currently the workqueue just checks the atomic and locking states after work execution ends. However, sometimes, a work item may not unlock rcu after acquiring rcu_read_lock(). And as a result, it would cause rcu stall, but the rcu stall warning can not dump the work func, because the work has finished. In order to quickly discover those works that do not call rcu_read_unlock() after rcu_read_lock(), add the rcu lock check. Use rcu_preempt_depth() to check the work's rcu status. Normally, this value is 0. If this value is bigger than 0, it means the work are still holding rcu lock. If so, print err info and the work func. tj: Reworded the description for clarity. Minor formatting tweak. Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com> Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com> Reviewed-by: Waiman Long <longman@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org> Stable-dep-of: de35994 ("workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from !WQ_MEM_RECLAIM worker") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 66e533f commit 2717b5e

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

kernel/workqueue.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,11 +2638,12 @@ __acquires(&pool->lock)
26382638
lock_map_release(&lockdep_map);
26392639
lock_map_release(&pwq->wq->lockdep_map);
26402640

2641-
if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
2642-
pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n"
2641+
if (unlikely(in_atomic() || lockdep_depth(current) > 0 ||
2642+
rcu_preempt_depth() > 0)) {
2643+
pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n"
26432644
" last function: %ps\n",
2644-
current->comm, preempt_count(), task_pid_nr(current),
2645-
worker->current_func);
2645+
current->comm, preempt_count(), rcu_preempt_depth(),
2646+
task_pid_nr(current), worker->current_func);
26462647
debug_show_held_locks(current);
26472648
dump_stack();
26482649
}

0 commit comments

Comments
 (0)