Skip to content

perf(network): VITA-49 stream socket uses ~208KB default SO_RCVBUF → burst drops trip the adaptive throttle (network stats drop) #3810

Description

@ten9876

Symptom

In-app network stats (stream rate / FPS / throughput) drop significantly at various times, then recover, on an otherwise-healthy LAN connection to a FLEX-8600.

Root cause (evidence-backed)

The VITA-49 UDP stream socket in PanadapterStream never raises SO_RCVBUF, so it uses the OS default (net.core.rmem_default ≈ 208 KB on Linux). Live evidence from a running session: one of the app's UDP stream sockets had 370 dropped datagrams (ss -md370) from receive-buffer overflow, against an rb212992 (~208 KB) buffer — and the drops arrived in a burst (not a steady leak).

The chain from there to the visible symptom:

  1. A burst of VITA-49 packets (panadapter FFT + waterfall tiles + audio + meters), or a brief worker-thread drain stall while the host is loaded, overflows the ~208 KB kernel buffer → the kernel silently drops the excess datagrams.
  2. Those drops show up as VITA-49 sequence gapsPanadapterStream::packetErrorCount() rises.
  3. RadioModel::evaluateNetworkQuality() folds packet loss into the quality score → m_netState degrades (Good/Fair/Poor).
  4. The adaptive throttle engages: applyAdaptiveFrameRate()sendAdaptiveCapToPan() sends display pan set <id> fps=<cap> to the radio (down to 4 fps in Poor).
  5. The radio streams fewer FFT/waterfall packets → network stats drop, held ≥ THROTTLE_MIN_DWELL_MS (5 s), then lift → re-trip on the next burst → "at various times."

Notably this is not a display artifact — the rate is computed as Δbytes ÷ actual-wall-clock elapsed, so it's robust to GUI-timer jitter. And the quality inputs (kernel-TCP_INFO ping RTT + VITA-49 loss) are GUI-thread-robust, so the throttle is reacting to real (but self-inflicted) loss.

Fix

Raise SO_RCVBUF on the bound VITA-49 socket to ~4 MiB so normal bursts/stalls are absorbed and don't surface as false sequence-loss. The kernel caps the request at net.core.rmem_max (4 MB on the test box); log the granted size so an undersized rmem_max is visible rather than silently limiting the buffer. Cross-platform (Linux/macOS/Windows).

Interaction with the render bottleneck (#3797)

The pegged GUI thread (#3797) makes overflow more likely (it can stall the socket drain during bursts), so this and #3797 compound — but the buffer is the directly fixable root for the stat-drop symptom.

Found while profiling the rendering work; PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    VITA-49VITA-49 UDP streaming: FFT, waterfall, audio, metersbugSomething isn't workingmaintainer-reviewRequires maintainer review before any action is takenpriority: mediumMedium priorityprotocolSmartSDR protocol

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions