From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit d79c7d01f1c8bcf9a48337c8960d618fbe31fc0c ]
If the controller has no buffers left return -ENOBUFF to indicate that iso_cnt might be out of sync.
Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES - The new guard in `net/bluetooth/iso.c:465` refuses to start a CIS if the socket has a TX SDU configured but the controller reports zero ISO credits even though there are no active ISO links (`hci_iso_count(hdev)` from `include/net/bluetooth/hci_core.h:1093`), signalling that the controller/host credit accounting has fallen out of sync. Without this check the connection succeeds but `hci_sched_iso()` never sends data because `hdev->iso_cnt` stays at zero, so user-space observes a “successful” connect that cannot carry audio. - The controller credit bookkeeping is expected to reset to `iso_pkts` when the buffer sizes are read (`net/bluetooth/hci_event.c:3770`) and to be restored on teardown (`net/bluetooth/hci_conn.c:1195`), so hitting this corner case indicates a real bug in the running system; returning `-ENOBUFS` makes that failure explicit instead of letting the socket hang. - Change scope is tiny (one extra check and error return in a single file) and it relies only on fields and helpers that have existed since ISO support shipped, so it backports cleanly and carries minimal regression risk.
net/bluetooth/iso.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 88602f19decac..247f6da31f9f3 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -460,6 +460,13 @@ static int iso_connect_cis(struct sock *sk) goto unlock; }
+ /* Check if there are available buffers for output/TX. */ + if (iso_pi(sk)->qos.ucast.out.sdu && !hci_iso_count(hdev) && + (hdev->iso_pkts && !hdev->iso_cnt)) { + err = -ENOBUFS; + goto unlock; + } + /* Just bind if DEFER_SETUP has been set */ if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,