Skip to content

drivers/usbdev/cdcncm: send TX immediately instead of after a tick-quantized delay#19469

Open
ricardgb wants to merge 1 commit into
apache:masterfrom
ricardgb:cdcncm-tx-latency
Open

drivers/usbdev/cdcncm: send TX immediately instead of after a tick-quantized delay#19469
ricardgb wants to merge 1 commit into
apache:masterfrom
ricardgb:cdcncm-tx-latency

Conversation

@ricardgb

Copy link
Copy Markdown
Contributor

Summary

cdcncm_send() defers each transmit to the work queue with a coalescing delay of
MSEC2TICK(CDCNCM_DGRAM_COMBINE_PERIOD), where CDCNCM_DGRAM_COMBINE_PERIOD is 1 (ms).
MSEC2TICK() quantizes to the system tick and rounds up, so on the default 100 Hz
tick (CONFIG_USEC_PER_TICK=10000) a "1 ms" delay becomes a full 10 ms tick — 10–20 ms
of real dead time once tick phase is included. As a result the reply to every
single-datagram exchange (ICMP echo, TCP ACK, a one-MSS HTTP segment) is parked in the
work queue for ~10–20 ms before EP_SUBMIT, which dominates the CDC-NCM round-trip time.

Because the coalescing window only ever batches datagrams that the network stack appends
within the same synchronous TX burst (which are already queued before the worker runs),
a non-zero inter-burst delay adds latency without providing any batching benefit in the
common one-datagram-at-a-time case. This change fires the transmit worker immediately
(delay 0); within-burst coalescing is preserved.

Impact

Measured on a Raspberry Pi Pico 2 W (RP2350) acting as a USB-NIC (CDC-NCM), default
100 Hz tick:

Before After
Ping RTT (avg) 21.7 ms 2.8 ms
HTTP GET of a 257 KB gzip page 5.79 s 0.92 s
Throughput 44.5 KB/s 279 KB/s

The RTT drop is the direct effect; the throughput gain follows because, without TCP write
buffers, the stack sends one segment per round trip, so throughput is ~MSS / RTT.

Testing

Validated on hardware (RP2350 / Pico 2 W, CDC-NCM over USB FS to a Linux host): ping RTT
and HTTP download measured before/after as above; served content verified byte-identical
(sha256) after the change. Not yet exercised on other platforms; the reasoning is
tick-rate-general (any board at the default 100 Hz tick is affected).


Disclosure: this change was prepared with the assistance of an AI agent (Anthropic's
Claude, via Claude Code). The root cause, fix, and on-hardware measurements were
reviewed by a human maintainer before submission.

@ricardgb
ricardgb requested a review from Donny9 as a code owner July 18, 2026 12:44
@github-actions github-actions Bot added Size: S The size of the change in this PR is small Area: USB labels Jul 18, 2026
@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

…antized delay

cdcncm_send() defers each transmit with MSEC2TICK(CDCNCM_DGRAM_COMBINE_PERIOD)
(1 ms). MSEC2TICK() rounds up to the system tick, so at the default 100 Hz tick
the "1 ms" coalescing window becomes a full 10 ms tick (10-20 ms with phase),
adding that latency to every single-datagram reply (ICMP echo, TCP ACK, one-MSS
HTTP segment) and dominating the CDC-NCM round-trip time.

The window only coalesces datagrams appended within the same synchronous TX
burst (already queued before the worker runs), so an inter-burst delay adds
latency without batching benefit in the common case. Fire the transmit worker
immediately (delay 0); within-burst coalescing is preserved.

On RP2350 (Pico 2 W) USB-NIC at 100 Hz tick: ping RTT 21.7 -> 2.8 ms, a 257 KB
HTTP download 5.79 -> 0.92 s (44.5 -> 279 KB/s).

Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Assisted-by: Claude (Anthropic Claude Code)
@ricardgb
ricardgb force-pushed the cdcncm-tx-latency branch from d18c44e to d1e7f27 Compare July 18, 2026 13:10
@linguini1

Copy link
Copy Markdown
Contributor

Please include the test logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: USB Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants