# DF-5369 — ums sc_lock <-> evdev ev_mtx lock-order inversion (unkillable open deadlock)

## What

`ums_intr_callback()` runs holding `sc->sc_lock` (the xfer priv lock,
`ums.c:606-608`) and calls `ums_evdev_push()` (`ums.c:363`, also
`ums.c:207` from the SBU callout) which takes the evdev state lock
(`ev_mtx`, because attach uses `evdev_register()`, `ums.c:743` ->
`evdev.c:345-347`).  Lock order A: **sc_lock -> ev_mtx**.

`evdev_register_client()` (`evdev.c:984-991`, from cdev open,
`cdev.c:132` under `EVDEV_LOCK`) and `evdev_unregister()` ->
`evdev_dispose_client()` (`evdev.c:375-388`, `evdev.c:1004-1008`,
detach) call the driver methods `ums_ev_open()`/`ums_ev_close()`
which take `sc->sc_lock` (`ums.c:964`, `ums.c:983`).  Lock order B:
**ev_mtx -> sc_lock**.

Two sleepable lockmgr locks acquired in opposite orders -> classic
AB-BA.  When an interrupt report and an open()/close() (or detach) hit
the µs-crossing simultaneously, BOTH sides block forever: the opener is
stuck in an unkillable D-state (`lockmgr` sleep has no PCATCH), the
USB callback thread is wedged holding `sc_lock`, and the input device
is dead.

## Reproduced (2/2 stock runs)

    # stock module, root open/close loop of the ums0 evdev node while
    # the QEMU mouse streams (~90 reports/s):
    t= 5s opens=6200
    t=10s opens=12600
    t=15s opens=19200
    t=20s opens=21200     <- froze; stream still flowing
    ... (counter never moves again)
    kill check: pids=31041 ; kill -9 ineffective ; loop never exits

    # ps forensics:
    PID   STAT WCHAN      COMMAND
    31041 D1   ums lock   /bin/sh /tmp/ocloop.sh

`WCHAN "ums lock"` is `sc->sc_lock` (lockinit'ed as "ums lock",
`ums.c:593`) — the opener is blocked exactly in `ums_ev_open()`'s
`lockmgr(&sc->sc_lock)` under `ev_mtx` while the callback holds
`sc_lock` and waits for `ev_mtx`.  Unkillable (D1), survived kill -9.

Second stock run froze even faster (1400 opens).

## Rig

Same as DF-5368 (QEMU usb-mouse on uhci, X86_64_GENERIC guest,
EVDEV_SUPPORT).  `ocprobe.py` drives everything.

## Run

    python3 ocprobe.py                       # stock /boot/kernel/ums.ko
    UMS_KO=/usr/src/.../ums.ko python3 ocprobe.py   # patched build

## Fix validation

`fix.diff`: register the evdev with the driver's lock —
`evdev_register_mtx(sc->sc_evdev, &sc->sc_lock)` — so both orders
become one recursive lock (`sc_lock` is `LK_CANRECURSE`, `ums.c:593`).

Patched run: 171,473 open/close cycles under continuous stream,
counter monotonic, loop exits on time, process killable, guest healthy
(fix_run.log).
