# DF-5183 — wait_on_bit_timeout() misuses the tsleep(9) API: Linux mode constants passed as sleep flags + unsigned-long timeout truncated to int

**File:** `sys/dev/drm/linux_wait.c:104-131` (`wait_on_bit_timeout`), `:141-144` (`wait_on_bit`)
**Severity:** Low — broken API contract; latent unkillable waits; 1 Hz polling instead of blocking
**Verdict:** REPRODUCED (deterministic, tsleep-level, no waker)

## Build / Run

Same module and procedure as the DF-5182 pack (this experiment rides in
the same `lwqdemo.ko`; the relevant output lines are prefixed `LWQ-F3:`):

```sh
cd /root/lwqdemo && make SYSDIR=/usr/src/sys && kldload ./lwqdemo.ko
sleep 8 && dmesg | grep LWQ-F3
```

## Expected output (decisive lines)

```
LWQ-F3: tsleep(timo=(int)MAX_SCHEDULE_TIMEOUT=-1) returned rv=35 after 2 ticks
        with NO waker - 'infinite' timeout actually expires every tick
LWQ-F3: wait_on_bit_timeout(MAX_SCHEDULE_TIMEOUT) on a set bit returned rv=0
        after 396 ticks (only exits because we clear the bit below; internally
        it polls at 1 tick granularity)
```

`rv=35` is `EWOULDBLOCK`: with no waker at all, a sleep whose timeout the
caller meant to be infinite (`MAX_SCHEDULE_TIMEOUT == LONG_MAX`) expires
after ~1 tick.

## Why (source chain)

* `wait_on_bit()` (linux_wait.c:141-144) passes `MAX_SCHEDULE_TIMEOUT`
  (`LONG_MAX`) into `wait_on_bit_timeout()`.
* `wait_on_bit_timeout()` (linux_wait.c:118) passes `timeout` straight to
  `tsleep(word, mode, "lwobt", timeout)`; `tsleep()`'s `timo` parameter is
  `int` (kern_synch.c:512), so `LONG_MAX` truncates to `-1`.
* `_callout_setup_quick()` (kern_timeout.c:940-976) computes
  `qtick = curticks - 1` and clamps it to `softticks + 1` — a next-tick
  callout. Every tsleep iteration therefore returns `EWOULDBLOCK` after
  one tick: "infinite" waits are 1 Hz polling loops (timer fire +
  context switch per waiter per tick).
* `mode` (TASK_RUNNING=0/TASK_INTERRUPTIBLE=1/TASK_UNINTERRUPTIBLE=2,
  sched.h:72-74) is also passed as the tsleep flags. `PCATCH` is 0x100
  (param.h:324), so `TASK_INTERRUPTIBLE` never requests signal delivery:
  an interruptible wait is silently uninterruptible (unkillable thread).
  The remaining low bits land in `PWAKEUP_CPUMASK` (param.h:327), which
  `tsleep` ignores for the sleep itself (`td_wdomain = flags &
  PDOMAIN_MASK`, kern_synch.c:448) — inert today, but the values are
  wrong on their face.

In-tree callers currently pass `TASK_UNINTERRUPTIBLE` only (i915_irq.c:3200,
i915_irq.c:3341), which is why this is latent rather than an active
defect; the truncation half is active in every `wait_on_bit()` call.

## Fix

`fix.diff` in this directory: translate `mode` → `PCATCH`, clamp the
timeout to 0 (= no timeout) instead of truncating.

## Artifacts

Same as the DF-5182 pack (`lwqdemo.c`, `Makefile`, `build.log`,
`run.log`, `env.txt`); the `LWQ-F3:` lines in `run.log` are this
finding's evidence. Reproduced twice (two guest boots), identical
numbers.
