zephyr/tests/bluetooth/host/keys
Johan Hedberg 39c2605930 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 <johan.hedberg@silabs.com>
2025-04-01 16:28:00 +02:00
..
bt_keys_add_type
bt_keys_clear
bt_keys_find
bt_keys_find_addr
bt_keys_find_irk
bt_keys_foreach_bond
bt_keys_foreach_type
bt_keys_get_addr tests/bluetooth/host/keys/bt_keys_get_addr: Correct mock prototypes 2024-10-29 09:24:13 -07:00
bt_keys_get_type
bt_keys_store
bt_keys_update_usage
mocks Bluetooth: Fix deadlock with settings and bt_hci_cmd_send_sync() 2025-04-01 16:28:00 +02:00
testing_common_defs.h