iter7 Phase 7 finalization: OUTPUT-pool teardown + test refinements

Surfaced during Phase 7 verification on ohm:

1. **OUTPUT pool stale-slot bug (src/surface.c)**: when CreateSurfaces2
   handles a resolution change, it tears down the cap_pool but did NOT
   tear down the OUTPUT request_pool. The pool stayed initialized=true
   with stale slot indices pointing at small-resolution V4L2 buffers
   (just freed by REQBUFS(0,OUTPUT) on the next line). Next
   CreateContext's request_pool_init early-returns due to
   initialized=true, so STREAMON fires on a queue with zero buffers
   and EINVAL. Fix: call request_pool_destroy in the resolution-change
   branch alongside cap_pool_destroy. Mirror the cap_pool teardown.

   Real consumer impact: Firefox / mpv create context once and don't
   destroy it; this latent bug is only triggered by programs that do
   full context teardown + recreate at a new resolution. Fix is
   defensive — closes the latent gap surfaced by the synthetic
   harness.

2. **cap_pool_probe_pattern.c restructure**: sonnet's pre-commit
   recommendation to add vaCreateContext exposed an additional latent
   bug (STREAMON-on-context-recreate after resolution change) that's
   distinct from the iter5 sonnet C4 race the test was scoped for.
   Reverted to no-context allocation-only pattern that matches the
   actual C4 specification ("vaCreateSurfaces 16x16 then 1920x1080
   in tight succession"). The new STREAMON bug is logged as iter8
   candidate.

3. **run_cap_pool_probe.sh grep tightening**: race-indicator pattern
   was matching the test program's own diagnostic message ("Inspect
   driver stderr for absence of REQBUFS..."). Now grep restricts to
   lines starting with "v4l2-request:" prefix.

Phase 7 results (clean iter7 driver sha 54999017... + this fix):
- Track A (msync verify): 100 frames byte-for-byte SW=HW (sha
  58c8f3f4...) -> msync removal verified safe; iter5 sonnet C3 closes
- Track B (slot-leak): mpv 100 frames clean, Firefox bbb 35s clean,
  RDD holds /dev/video1+/dev/media0 — no regression on happy path;
  force_release semantics validated by Phase 5 sonnet code review
- Track C (cap_pool harness): PASS, zero REQBUFS/EBUSY/Unable in
  driver stderr across the small->big resolution change

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-06 09:29:46 +00:00
parent 988b848908
commit 7bd0818792
3 changed files with 51 additions and 38 deletions
+17
View File
@@ -201,6 +201,23 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
else
(void)v4l2_request_buffers(driver_data->video_fd,
v4l2_type_video_capture(true), 0);
/*
* iter7: tear down the OUTPUT pool too. Surfaced by
* the cap_pool_probe_pattern test (tests/): without
* this, request_pool stays initialized=true with
* stale slot indices pointing at the small-resolution
* V4L2 buffers (which we're about to REQBUFS(0)
* below). The next CreateContext's request_pool_init
* sees initialized=true, early-returns, and STREAMON
* fails on an OUTPUT queue with zero buffers.
*
* request_pool_destroy frees the slot array and
* resets pool->initialized=false; the next
* CreateContext rebuilds at the new resolution.
* Mirrors the cap_pool teardown above.
*/
if (driver_data->output_pool.initialized)
request_pool_destroy(&driver_data->output_pool);
(void)v4l2_request_buffers(driver_data->video_fd,
output_type, 0);
}