[PATCH 0/6] USB: serial: ftdi_sio: configurable read-URB defer, per-port low_latency, latency_timer reliability
From: Chinna Mopurigari Naveen Kumar Reddy
Date: Mon Jun 22 2026 - 03:41:18 EST
This series adds an opt-in mechanism to bound ftdi_sio's read-URB
resubmission rate, a per-port escape hatch for it, and two small
reliability fixes to the existing latency_timer sysfs attribute. None
of it changes the driver's default behaviour.
Background
==========
ftdi_sio resubmits read URBs as fast as the previous URB completes.
On host controllers that do not arbitrate DMA-channel allocation
between devices, a single FT4232 at high baud (4 channels x ~916 kbps)
can keep most or all of the controller's DMA channels occupied;
multiple FT4232 chips on the same bus exhaust them entirely. The
control endpoint and unrelated devices on the same bus then make no
progress -- device enumeration fails, hub events stall. The
BCM2835/BCM2837 DWC_OTG controller used on the Raspberry Pi Compute
Module 3 is the platform where this was characterised.
This series introduces a small inter-batch defer on read-URB
resubmission that bounds per-device DMA-channel occupancy. It is
disabled by default; behaviour on every unaffected host is unchanged.
Series layout
=============
Patch 1 adds the inter-batch defer and the urb_defer_timer_ns module
parameter that controls it (default 0 = disabled). It also adds a
small helper, ftdi_atomic_submit_read_urbs(), used wherever read URBs
are resubmitted from completion or hrtimer (atomic) context:
usb_serial_generic_submit_read_urbs() looks atomic-usable because it
takes a gfp_t, but its error-recovery path calls usb_kill_urb(), which
sleeps -- so a failed inner submit under bus pressure would sleep in
atomic context. The helper submits each URB inline with
usb_submit_urb(GFP_ATOMIC), which does not sleep.
Patch 2 wraps usb_control_msg() with a retry on the documented
transient errno values (-ETIMEDOUT, -EPIPE, -EPROTO) seen under heavy
bus pressure, and converts write_latency_timer() to use it.
Patch 3 makes an explicit sysfs write to .../latency_timer
authoritative against the legacy ASYNC_LOW_LATENCY tty-flag clamp set
via TIOCSSERIAL by tools such as setserial(8).
Patch 4 adds a per-port low_latency sysfs attribute that bypasses the
inter-batch defer on a single port when the defer is globally enabled.
Patch 5 serialises the low_latency toggle against the read-bulk
callback so the attribute can be flipped while a port is actively
reading or writing.
Patch 6 adds a low_latency_defer_ns module parameter: instead of fully
bypassing the defer, a low_latency port can be paced with a small
per-port interval (e.g. 2 ms), which lets several low_latency ports
run concurrently without re-starving control transfers.
Testing
=======
Functionally validated on the affected hardware (Raspberry Pi Compute
Module 3, BCM2837 DWC_OTG, two FT4232 chips, eight RS485 channels at
916 kbps each) on the 6.12 stable kernel: with the defer enabled,
worst-case control-transfer latency under concurrent load dropped from
~50 ms (stock) to ~1 ms; per-port low_latency restores native read
latency on a chosen port; the paced path (low_latency_defer_ns=2ms)
lets four low_latency ports run without starving control transfers or
the USB-Ethernet path.
Runtime-tested on mainline at the series base (arm64, Raspberry Pi 4,
VL805 xHCI host, CONFIG_DEBUG_ATOMIC_SLEEP=y): module load/unload,
default-path loopback regression check, the deferred-resubmit path
(urb_defer_timer_ns=30ms) with live data, low_latency toggling under
load (200 cycles, no stall), explicit latency_timer writes, the paced
low_latency path (low_latency_defer_ns=2ms), and 50x open/close churn
-- all pass with no atomic-context splats. Note this host does not
reproduce the DMA-starvation problem (that requires the DWC_OTG
controller); the mainline run is functional validation of the new
code paths.
scripts/checkpatch.pl --strict is clean on every patch.
Chinna Mopurigari Naveen Kumar Reddy (6):
USB: serial: ftdi_sio: add configurable inter-batch defer for read
URBs
USB: serial: ftdi_sio: retry transient errors on chip-side control
transfers
USB: serial: ftdi_sio: make explicit latency_timer sysfs write
authoritative
USB: serial: ftdi_sio: add per-port low_latency sysfs attribute
USB: serial: ftdi_sio: serialise low_latency toggle against
read_bulk_callback
USB: serial: ftdi_sio: pace low_latency ports with
low_latency_defer_ns
drivers/usb/serial/ftdi_sio.c | 488 +++++++++++++++++++++++++++++++++-
1 file changed, 480 insertions(+), 8 deletions(-)
base-commit: ba3e43a9e601636f5edb54e259a74f96ca3b8fd8
--
2.43.0