Commit fb5e1de
Bluetooth: Fix deadlock with settings and bt_hci_cmd_send_sync()
We can't do synchronous HCI command sending in any settings commit()
callback, since we don't know what context the callback is being called
from. One particular deadlock can happen if settings_load() is called from
the preemptible main thread:
main()
|--> settings_load() (aquire settings_lock mutex)
|-->commit callback A that defers to system wq
|-->commit callback B that calls bt_hci_cmd_send_sync()
system wq from the previous deferral from within settings_load():
|--> work item
|--> settings_save_one()
|--> attempt to aquire settings_lock mutex
In the above scenario, the bt_hci_cmd_send_sync() call from the main thread
depends on the system workqueue being processed (since that's what does HCI
command processing by default), while at the same time holding the settings
subsystem's mutex. At the same time, a system wq item tries to store
something into settings, however it deadlocks waiting for the settings
mutex.
The actual scenario that we have in the Bluetooth subsystem is where
"commit callback A" is commit_settings() in host/settings.c, and "commit
callback B" is keys_commit() in host/keys.c.
The solution to the deadlock is to take advantage of deferred bt_id_add()
handling which already exists, i.e. set a flag and deferre the actual
adding to the system workqueue.
Signed-off-by: Johan Hedberg <[email protected]>
(cherry picked from commit 39c2605)
Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>1 parent e59205c commit fb5e1de
5 files changed
+26
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
866 | 866 | | |
867 | 867 | | |
868 | 868 | | |
869 | | - | |
| 869 | + | |
870 | 870 | | |
871 | 871 | | |
872 | 872 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
8 | 10 | | |
9 | 11 | | |
10 | 12 | | |
| |||
44 | 46 | | |
45 | 47 | | |
46 | 48 | | |
| 49 | + | |
| 50 | + | |
47 | 51 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| |||
426 | 427 | | |
427 | 428 | | |
428 | 429 | | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
429 | 437 | | |
430 | 438 | | |
431 | 439 | | |
432 | 440 | | |
433 | | - | |
| 441 | + | |
| 442 | + | |
434 | 443 | | |
435 | 444 | | |
436 | 445 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
15 | 18 | | |
16 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
0 commit comments