Public bug reported: # uvcvideo: unkillable deadlock in status-event / PM path (kernel 7.0)
Draft for: Launchpad (`ubuntu-bug linux`, tag `regression-update`) and [email protected] (CC uvcvideo maintainer + granular-PM series author). Status: draft, 2026-07-15. Traces: `uvcvideo-deadlock-traces.txt` (same directory). ## Summary Control access to an Intel RealSense D405 (USB 8086:0b5b) reliably wedges the whole USB host stack on Ubuntu kernel 7.0.0-27-generic (also present, by code inspection, in upstream v7.0.6 and current mainline). The triggering process enters uninterruptible sleep (unkillable, survives SIGKILL), and the device's USB disconnect path then deadlocks the hub workqueue (`usb_hub_wq` in D state), after which no device on that hub can enumerate. Only a reboot recovers. ## Root cause (source analysis, drivers/media/usb/uvc) `uvc_ctrl_set_handle()` takes a PM reference (`uvc_pm_get`) for a pending async control, released by `uvc_ctrl_clear_handle()` -> `uvc_pm_put()` when the control-change status event arrives. That release runs inside `uvc_ctrl_status_event()`, which is invoked from two contexts where dropping the LAST status user deadlocks: 1. From the async worker `uvc_ctrl_status_event_work()`: `uvc_pm_put` -> `uvc_status_put` (takes `status_lock`) -> `uvc_status_stop` -> `cancel_work_sync(&dev->async_ctrl.work)` — cancelling the work item it is currently executing in. Waits for itself forever, holding `status_lock`. 2. From `uvc_status_stop()` itself (the synchronous flush, `if (cancel_work_sync(&w->work)) uvc_ctrl_status_event(...)`): the same put chain then re-acquires `status_lock`, which the caller (`uvc_status_put`/`uvc_status_suspend`) already holds. Self-deadlock on a non-recursive mutex. Every subsequent open/ioctl blocks in `uvc_status_get()` on `status_lock` (observed hung tasks), and `uvc_status_unregister()` -> `uvc_status_suspend()` blocks the USB disconnect path, freezing the hub workqueue. ## Observed impact (hardware reproduction) - Machine: omen rig, Ubuntu resolute, kernel 7.0.0-27-generic, 2x Intel RealSense D405 + 1x D435 on the same bus. - One D405 unit hits the race nearly every time on XU control access (its firmware emits the status event at the fatal moment); the other unit survives identical commands. Reproduced via librealsense enumeration AND via minimal raw UVCIOC_CTRL_QUERY ioctls; also right after a clean boot. - Hung-task stacks captured in `uvcvideo-deadlock-traces.txt` show both sides: `uvc_v4l2_unlocked_ioctl -> uvc_status_get` blocked, and `Workqueue: events uvc_ctrl_status_event_work -> uvc_ctrl_status_event -> uvc_pm_put -> uvc_status_put -> uvc_status_stop` blocked. - No uvcvideo changes between Ubuntu 7.0.0-14 and -27 (changelog); not an Ubuntu-local regression. `uvc_status.c` identical in mainline as of 2026-07-15; no fix or report found on linux-media/patchwork. ## Suggested direction for a fix Dropping the pending-async-control PM reference must not synchronously stop the status URB from the event-delivery contexts. Options: defer the final `uvc_status_stop()` to a separate work item when called from the async worker (`current_work() == &dev->async_ctrl.work`), or drop the reference outside `status_lock` / outside the worker. The synchronous-flush path (2) additionally must not re-enter `uvc_status_put` under `status_lock`. ## Verification (2026-07-15, same machine) - Firmware dependence of the trigger: on camera FW 5.15.1.55 one D405 unit wedged nearly every XU control access and the other rarely; after updating both cameras to FW 5.17.3.10 the deadlock became DETERMINISTIC on both units (first control-change sequence wedges both cameras, reproduced immediately after a clean boot). Newer firmware appears to deliver the async control-change status event more reliably, hitting the race window every time. - Workaround validation: with the patched module (status endpoint never armed, see below), the identical control sequences complete with zero hangs across repeated apply/hammer cycles on both FW versions' event behavior. Side effect observed: async controls (AE/exposure) remain "pending" forever (GET returns EBUSY) since the confirmation event never arrives — consistent with uvc_ctrl_set_handle never being cleared, and benign for operation (SETs land; streaming unaffected). ## Local mitigation deployed on this machine Out-of-tree build of uvcvideo 7.0.0-27 with a `disable_status` module parameter that skips `uvc_status_init()` URB arming entirely (no status events -> no worker -> no deadlock; costs async control-change notifications and camera-button events). Installed under `/lib/modules/7.0.0-27-generic/updates/`, enabled via `/etc/modprobe.d/uvcvideo-rig.conf`. ProblemType: Bug DistroRelease: Ubuntu 26.04 Package: linux-image-7.0.0-27-generic 7.0.0-27.27 ProcVersionSignature: Ubuntu 7.0.0-27.27-generic 7.0.6 Uname: Linux 7.0.0-27-generic x86_64 ApportVersion: 2.34.0-0ubuntu2 Architecture: amd64 AudioDevicesInUse: USER PID ACCESS COMMAND /dev/snd/controlC2: robocurve 5721 F.... wireplumber /dev/snd/controlC0: robocurve 5721 F.... wireplumber /dev/snd/controlC1: robocurve 5721 F.... wireplumber /dev/snd/seq: robocurve 5703 F.... pipewire CasperMD5CheckResult: unknown CurrentDesktop: ubuntu:GNOME Date: Thu Jul 16 00:03:18 2026 InstallationDate: Installed on 2026-06-29 (16 days ago) InstallationMedia: Ubuntu 26.04 "Resolute Raccoon" - Release amd64 (20260423.1) MachineType: HP OMEN by HP 45L Gaming Desktop GT22-3xxx ProcEnviron: LANG=en_US.UTF-8 PATH=(custom, no user) SHELL=/bin/bash TERM=tmux-256color XDG_RUNTIME_DIR=<set> ProcFB: 0 nvidia-drmdrmfb ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-7.0.0-27-generic root=UUID=1639853a-6154-4c17-954d-08761337d8ae ro quiet splash crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M SourcePackage: linux UpgradeStatus: No upgrade log present (probably fresh install) dmi.bios.date: 11/13/2025 dmi.bios.release: 15.32 dmi.bios.vendor: AMI dmi.bios.version: F.20 dmi.board.name: 8D2C dmi.board.vendor: HP dmi.board.version: 00 dmi.chassis.type: 3 dmi.chassis.vendor: HP dmi.ec.firmware.release: 36.15 dmi.modalias: dmi:bvnAMI:bvrF.20:bd11/13/2025:br15.32:efr36.15:svnHP:pnOMENbyHP45LGamingDesktopGT22-3xxx:pvr:rvnHP:rn8D2C:rvr00:cvnHP:ct3:cvr:skuB91WJAA#ABA:pfa103C_5331M5HPOMEN: dmi.product.family: 103C_5331M5 HP OMEN dmi.product.name: OMEN by HP 45L Gaming Desktop GT22-3xxx dmi.product.sku: B91WJAA#ABA dmi.sys.vendor: HP ** Affects: linux (Ubuntu) Importance: Undecided Status: New ** Tags: amd64 apport-bug resolute wayland-session -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2160752 Title: uvcvideo: unkillable deadlock in status-event/PM path wedges USB stack (RealSense D405) To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2160752/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
