USB: serial: ftdi_sio: configurable read-URB defer, per-port low_latency, latency_timer reliability
Get series with b4
b4 am [email protected]Versions newest first
- v1 Latest6 patches 5 repliesIn review
Patches in v1 No applies recorded yet
| # | Subject and files | Size | Replies | Applied |
|---|---|---|---|---|
| 1/6 | USB: serial: ftdi_sio: add configurable inter-batch defer for read URBsdrivers/ | +273 | 5 replies | |
| 2/6 | USB: serial: ftdi_sio: retry transient errors on chip-side control transfersdrivers/ | +41 | 0 replies | |
| 3/6 | USB: serial: ftdi_sio: make explicit latency_timer sysfs write authoritativedrivers/ | +17 | 0 replies | |
| 4/6 | USB: serial: ftdi_sio: add per-port low_latency sysfs attributedrivers/ | +66 | 0 replies | |
| 5/6 | USB: serial: ftdi_sio: serialise low_latency toggle against read_bulk_callbackdrivers/ | +52 | 0 replies | |
| 6/6 | USB: serial: ftdi_sio: pace low_latency ports with low_latency_defer_nsdrivers/ | +43 | 0 replies |
Reviews trailers per patch
No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.
Cover letter [PATCH 0/6] USB: serial: ftdi_sio: configurable read-URB defer, per-port low_latency, latency_timer reliability
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
Signature · 1 line
2.43.0