Skip to content
Commit 39c26059 authored by Johan Hedberg's avatar Johan Hedberg Committed by Benjamin Cabé
Browse files

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: default avatarJohan Hedberg <johan.hedberg@silabs.com>
parent 58ea18ed
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment