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

Reply via email to