From 6b0242cfeb5cf8275187062d24910683ddaf9486 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 1 Aug 2019 17:16:45 +0300 Subject: [PATCH] Bluetooth: Fix deadlock caused by blocking on syswq Since TX complete notification are dispatched with syswq blocking on it can completely deadlock Bluetooth so this attempt to make it safe by return -ENOMEM if that the current thread happens to be the syswq thread. Signed-off-by: Luiz Augusto von Dentz --- subsys/bluetooth/host/conn.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 2e150999842..4e72b607eb3 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2290,10 +2290,18 @@ struct net_buf *bt_conn_create_pdu(struct net_buf_pool *pool, size_t reserve) pool = &acl_tx_pool; } - if (IS_ENABLED(CONFIG_BT_DEBUG_CONN)) { + if (IS_ENABLED(CONFIG_BT_DEBUG_CONN) || + k_current_get() == &k_sys_work_q.thread) { buf = net_buf_alloc(pool, K_NO_WAIT); if (!buf) { BT_WARN("Unable to allocate buffer"); + /* Cannot block with K_FOREVER on k_sys_work_q as that + * can cause a deadlock when trying to dispatch TX + * notification. + */ + if (k_current_get() == &k_sys_work_q.thread) { + return NULL; + } buf = net_buf_alloc(pool, K_FOREVER); } } else {