Commit be2355b
workqueue: Provide one lock class key per work_on_cpu() callsite
[ Upstream commit 265f3ed ]
All callers of work_on_cpu() share the same lock class key for all the
functions queued. As a result the workqueue related locking scenario for
a function A may be spuriously accounted as an inversion against the
locking scenario of function B such as in the following model:
long A(void *arg)
{
mutex_lock(&mutex);
mutex_unlock(&mutex);
}
long B(void *arg)
{
}
void launchA(void)
{
work_on_cpu(0, A, NULL);
}
void launchB(void)
{
mutex_lock(&mutex);
work_on_cpu(1, B, NULL);
mutex_unlock(&mutex);
}
launchA and launchB running concurrently have no chance to deadlock.
However the above can be reported by lockdep as a possible locking
inversion because the works containing A() and B() are treated as
belonging to the same locking class.
The following shows an existing example of such a spurious lockdep splat:
======================================================
WARNING: possible circular locking dependency detected
6.6.0-rc1-00065-g934ebd6e5359 #35409 Not tainted
------------------------------------------------------
kworker/0:1/9 is trying to acquire lock:
ffffffff9bc72f30 (cpu_hotplug_lock){++++}-{0:0}, at: _cpu_down+0x57/0x2b0
but task is already holding lock:
ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 ((work_completion)(&wfc.work)){+.+.}-{0:0}:
__flush_work+0x83/0x4e0
work_on_cpu+0x97/0xc0
rcu_nocb_cpu_offload+0x62/0xb0
rcu_nocb_toggle+0xd0/0x1d0
kthread+0xe6/0x120
ret_from_fork+0x2f/0x40
ret_from_fork_asm+0x1b/0x30
-> #1 (rcu_state.barrier_mutex){+.+.}-{3:3}:
__mutex_lock+0x81/0xc80
rcu_nocb_cpu_deoffload+0x38/0xb0
rcu_nocb_toggle+0x144/0x1d0
kthread+0xe6/0x120
ret_from_fork+0x2f/0x40
ret_from_fork_asm+0x1b/0x30
-> #0 (cpu_hotplug_lock){++++}-{0:0}:
__lock_acquire+0x1538/0x2500
lock_acquire+0xbf/0x2a0
percpu_down_write+0x31/0x200
_cpu_down+0x57/0x2b0
__cpu_down_maps_locked+0x10/0x20
work_for_cpu_fn+0x15/0x20
process_scheduled_works+0x2a7/0x500
worker_thread+0x173/0x330
kthread+0xe6/0x120
ret_from_fork+0x2f/0x40
ret_from_fork_asm+0x1b/0x30
other info that might help us debug this:
Chain exists of:
cpu_hotplug_lock --> rcu_state.barrier_mutex --> (work_completion)(&wfc.work)
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock((work_completion)(&wfc.work));
lock(rcu_state.barrier_mutex);
lock((work_completion)(&wfc.work));
lock(cpu_hotplug_lock);
*** DEADLOCK ***
2 locks held by kworker/0:1/9:
#0: ffff900481068b38 ((wq_completion)events){+.+.}-{0:0}, at: process_scheduled_works+0x212/0x500
#1: ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500
stack backtrace:
CPU: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.6.0-rc1-00065-g934ebd6e5359 #35409
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
Workqueue: events work_for_cpu_fn
Call Trace:
rcu-torture: rcu_torture_read_exit: Start of episode
<TASK>
dump_stack_lvl+0x4a/0x80
check_noncircular+0x132/0x150
__lock_acquire+0x1538/0x2500
lock_acquire+0xbf/0x2a0
? _cpu_down+0x57/0x2b0
percpu_down_write+0x31/0x200
? _cpu_down+0x57/0x2b0
_cpu_down+0x57/0x2b0
__cpu_down_maps_locked+0x10/0x20
work_for_cpu_fn+0x15/0x20
process_scheduled_works+0x2a7/0x500
worker_thread+0x173/0x330
? __pfx_worker_thread+0x10/0x10
kthread+0xe6/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x2f/0x40
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1b/0x30
</TASK
Fix this with providing one lock class key per work_on_cpu() caller.
Reported-and-tested-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>1 parent 3073f6d commit be2355b
2 files changed
+51
-15
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
274 | 274 | | |
275 | 275 | | |
276 | 276 | | |
277 | | - | |
| 277 | + | |
278 | 278 | | |
279 | | - | |
280 | | - | |
281 | 279 | | |
282 | 280 | | |
283 | | - | |
| 281 | + | |
284 | 282 | | |
285 | 283 | | |
286 | 284 | | |
287 | 285 | | |
288 | | - | |
| 286 | + | |
289 | 287 | | |
290 | 288 | | |
291 | 289 | | |
| |||
294 | 292 | | |
295 | 293 | | |
296 | 294 | | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
297 | 302 | | |
298 | 303 | | |
299 | 304 | | |
300 | 305 | | |
301 | 306 | | |
302 | 307 | | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
303 | 311 | | |
304 | 312 | | |
305 | 313 | | |
| |||
693 | 701 | | |
694 | 702 | | |
695 | 703 | | |
696 | | - | |
697 | | - | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
698 | 730 | | |
699 | 731 | | |
700 | 732 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5622 | 5622 | | |
5623 | 5623 | | |
5624 | 5624 | | |
5625 | | - | |
| 5625 | + | |
5626 | 5626 | | |
5627 | 5627 | | |
5628 | 5628 | | |
| 5629 | + | |
5629 | 5630 | | |
5630 | 5631 | | |
5631 | 5632 | | |
5632 | 5633 | | |
5633 | 5634 | | |
5634 | 5635 | | |
5635 | | - | |
| 5636 | + | |
| 5637 | + | |
5636 | 5638 | | |
5637 | 5639 | | |
5638 | 5640 | | |
5639 | | - | |
| 5641 | + | |
5640 | 5642 | | |
5641 | 5643 | | |
5642 | 5644 | | |
5643 | 5645 | | |
5644 | 5646 | | |
5645 | | - | |
| 5647 | + | |
5646 | 5648 | | |
5647 | 5649 | | |
5648 | | - | |
| 5650 | + | |
5649 | 5651 | | |
5650 | 5652 | | |
5651 | 5653 | | |
| 5654 | + | |
5652 | 5655 | | |
5653 | 5656 | | |
5654 | 5657 | | |
5655 | 5658 | | |
5656 | 5659 | | |
5657 | 5660 | | |
5658 | | - | |
| 5661 | + | |
| 5662 | + | |
5659 | 5663 | | |
5660 | 5664 | | |
5661 | 5665 | | |
5662 | 5666 | | |
5663 | 5667 | | |
5664 | | - | |
| 5668 | + | |
5665 | 5669 | | |
5666 | 5670 | | |
5667 | 5671 | | |
5668 | | - | |
| 5672 | + | |
5669 | 5673 | | |
5670 | 5674 | | |
5671 | 5675 | | |
| |||
0 commit comments