Bluetooth: Host: Invoke tx callbacks when channel is deleted #97056
+15
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When bt_l2cap_send_pdu() succeeds, it transfers buffer ownership to the stack, which must eventually invoke the provided callback. This contract is honored in all paths where transmission becomes impossible:
However, when a channel is deleted (l2cap_chan_del), PDUs remaining in the tx_queue are dropped without invoking their callbacks, violating the ownership contract.
Fix this by extracting and invoking any non-NULL callbacks from the closure stored in buf->user_data before releasing the buffers. The callback is invoked with err=-ESHUTDOWN, making this path analogous to process_unack_tx: both drain queues of unsent PDUs when transmission becomes impossible due to external events (channel deletion vs connection disconnect). The only difference is the buffer lifecycle stage - in l2cap_chan_del, PDUs are still in tx_queue (closure in buf->user_data), while in process_unack_tx, they've progressed to tx_pending (callback in bt_conn_tx struct).
Note: conn_tx_destroy() cannot be used here because no bt_conn_tx struct has been allocated yet - the closure is still in buf->user_data.