# DF-4401 — Unguarded tws_reset() re-entry: check-then-act race corrupts the reset state machine (panic / frozen simq)

## What
`tws_reset()` (`sys/dev/raid/tws/tws_cam.c:1197-1218`) guards re-entry with an
**unlocked** read:

```c
if ( tws_get_state(sc) == TWS_RESET ) {
    return;
}
...
lockmgr(&sc->gen_lock, LK_EXCLUSIVE);
tws_send_event(sc, TWS_RESET_START);   /* KASSERT(state != TWS_RESET), tws.c:666 */
lockmgr(&sc->gen_lock, LK_RELEASE);
```

Three independent callers can run it concurrently:
- `tws_timeout` ccb-timeout callout (`tws_cam.c:1185-1195`) — one per queued I/O;
- `tws_intr_attn_error` microcontroller-error interrupt (`tws_cam.c:1143-1153`);
- `tws_passthru` ioctl thread on ETIMEDOUT (`tws_user.c:143-147`, holding
  `gen_lock` — only survivable because it is `LK_CANRECURSE`, `tws.c:199`).

Two threads that both pass the unlocked check both execute the reset prologue:

1. **INVARIANTS kernels:** the second `TWS_RESET_START` trips
   `KASSERT(sc->tws_state != TWS_RESET)` (`tws.c:666`) → panic
   (`KASSERT`/`KKASSERT` are compiled in only with INVARIANTS,
   `sys/sys/systm.h:94-122`); the second `TWS_RESET_COMPLETE` later trips
   `tws.c:674` similarly.
2. **Production kernels:** duplicated `xpt_freeze_simq(sc->sim, 1)`
   (`tws_cam.c:1212-1214`) with only ONE matching `xpt_release_simq(...,1)` in
   `tws_reinit` (`:1268-1270`) → `qfrozen_cnt` leaks ≥1
   (`sys/bus/cam/cam_xpt.c:4852-4888`) → **the SIM queue stays frozen forever,
   all I/O on the adapter stalls permanently**; plus a duplicated soft reset
   (`tws_assert_soft_reset`, `:1216`) and duplicated `reset_cb`/`reinit`
   callout chains.
3. `tws_reinit()` (`:1241-1281`) keeps its retry counters (`timeout_val`,
   `try`) in `static` storage — shared across all adapters in the system.

Sibling: DF-4336 (twa `tw_cl_reset_ctlr` has no entry guard) — same defect class
carried into the tws CAM layer.

## Impact
Local DoS (panic on debug kernels; permanent adapter I/O freeze on production
kernels) triggered by controller distress that fires ≥2 of the reset callers
near-simultaneously (e.g. two ccb timeouts racing a controller-error
interrupt). No privilege needed beyond ordinary I/O to a distressed adapter.

## Status
QEMU guest has no 3ware HBA → inconclusive; race proven from source.
