Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion subsys/usb/device_next/class/usbd_cdc_acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,7 @@ static void cdc_acm_poll_out(const struct device *dev, const unsigned char c)
struct cdc_acm_uart_data *const data = dev->data;
k_spinlock_key_t key;
uint32_t wrote;
int retries = 20;

while (true) {
key = k_spin_lock(&data->lock);
Expand All @@ -1019,7 +1020,15 @@ static void cdc_acm_poll_out(const struct device *dev, const unsigned char c)
break;
}

if (k_is_in_isr() || !data->flow_ctrl) {
/* Bounded wait: with an attached-but-stalled host session (macOS
* ceases IN polling for minutes at a time), an unbounded sleep-retry
* here makes every console write take the full stall duration. Any
* thread that logs (event text loggers, assert reporting) then backs
* up its own queues and cascades into a system-wide com livelock.
* After ~20 ms of backpressure, treat the console as best-effort and
* discard, exactly like the detached (!flow_ctrl) case below.
*/
if (k_is_in_isr() || !data->flow_ctrl || retries-- <= 0) {
LOG_WRN_ONCE("Ring buffer full, discard data");
break;
}
Expand Down
Loading