Skip to content

vms-648: cache the ACP backing-device handle so PRODUCT INSTALL stops timing out (R1 e2e) - #881

Merged
baron-3dl merged 1 commit into
mainfrom
work/vms-648-acp-bdev-cache
Aug 29, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
work/vms-648-acp-bdev-cache

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

Summary

The R1 release-install e2e (vms-37f) went red 6 passed / 10 failed on main. The symptom read as non-persistence (SCSNODE, SYSTEM credential, USERS.* home dirs all failing to land on the target), but the real cause is upstream of any write: container 1 hangs at Configuring OVMX ... OpenVMS Operating System and never reaches %PCSI-I-DONE within the harness's 90s per-step timeout. AUTHORIZE / SYSGEN / the USERS tree never run — the "non-persistence" is a downstream consequence of PCSI being killed mid-install.

This is NOT a code regression in the window

Built the bootable image at the known-good baseline 7811bf30 and the known-bad tip 9c507bc6 and ran the install under --cpus=1 (the slow single-CPU TCG profile a GitHub runner presents):

image install under --cpus=1
baseline 7811bf30 FATAL, 7/21 — hung at Configuring
bad-tip 9c507bc6 FATAL, 7/21 — hung at Configuring
this fix 21/21, full install in 72s

No commit in 7811bf30..9c507bc6 touches the ACP write hot path (the two vms_lock.c DLM changes only alter cross-node xn-guarded code; #846/#870/#871 are Alpha-tooling test-only; the OS kit is byte-identical 4.4M at both ends). The CI "baseline green / bad-tip red" was runner-speed variance across a razor-thin margin, not a product change. Confirmed against the actual failing CI job (run 33218016964, job 99005938554) and the green baseline job (run 33190974044, job 98928619663).

Root cause

exec_blockdev_read_block/write_block (exec_kbackend_linux.h) open AND close the backing block device (bdev_file_open_by_dev + fput) and alloc a page for every 512-byte LBN. PRODUCT INSTALL writes the ~4.4M OS kit as thousands of blocks — thousands of full bdev open/close cycles — which under single-CPU TCG exceeds 90s. The NetBSD twin already caches its backing vnode (vms_blockdev_netbsd.c); this is the missing Linux equivalent.

Fix

A module-global backing-device handle cache (exec_bdev_get_cached / exec_bdev_cache_release_all in vms_module.c): each device opened once (READ|WRITE, non-exclusive), keyed by dev_t, reused for every block; released together at module exit (vms_exit), the OS-lifetime analogue of NetBSD's release-at-detach. Slots are only added, never evicted mid-life, so a handed-back block_device stays valid across the bio (which runs outside the cache lock) — no use-after-free. A full table or failed open returns NULL and the primitives fall back to the original open-per-call path, so correctness never depends on the cache. Only the OPEN is amortized; every block is still a real synchronous bio to a real device (INV-6 / Rule 8). The test is unchanged — not weakened.

Proof (real /dev/vms, qemu-system-x86_64, TCG, --cpus=1)

Full 16-check R1 gate, all containers --cpus=1, this fix: RESULTS: 16 passed, 0 failed — SCSNODE OVMXR1 persists, SYSTEM logs in with the install-set password, PRODUCT SHOW + DIRECTORY resolve, USERS home dirs resolve, negctl boundary intact.

NetBSD unaffected (backend already caches; new symbols are Linux-only). Standalone vms.ko builds+modposts on 6.8 (pre-6.9 branch); in-tree bootable module builds+modposts on 6.12 (post-6.9 branch).

🤖 Generated with Claude Code

… timing out (R1 e2e)

The R1 release-install e2e (vms-37f) went red 6/10 on main after the blind
YAML-broken window. The signature looked like non-persistence — SCSNODE,
SYSTEM credential and USERS.* home dirs all failing to land on the target —
but the real cause is upstream of any write: container 1 HANGS at
"Configuring OVMX ... OpenVMS Operating System" and never reaches
%PCSI-I-DONE within the harness's 90s per-step timeout, so AUTHORIZE / SYSGEN
/ the USERS tree never run at all. The "non-persistence" is a downstream
symptom of PCSI being killed mid-install.

Not a code regression in the window. Built at the KNOWN-GOOD baseline 7811bf3
and the KNOWN-BAD tip 9c507bc and ran the install under `--cpus=1` (the slow
single-CPU TCG profile a GitHub runner presents): BOTH fail identically at
7/21, hung at Configuring. No commit in 7811bf3..9c507bc touches the ACP
write hot path (the two vms_lock.c DLM changes only alter cross-node,
xn-guarded code; #846/#870/#871 are Alpha-tooling test-only; the OS kit is
byte-identical 4.4M at both ends). The CI "baseline green / bad-tip red" was
runner-speed variance across a razor-thin margin, not a product change.

Root cause: exec_blockdev_read_block/write_block (exec_kbackend_linux.h) open
AND close the backing block device (bdev_file_open_by_dev + fput) and alloc a
page for EVERY 512-byte LBN. PRODUCT INSTALL writes the ~4.4M OS kit as
thousands of blocks, so that is thousands of full bdev open/close cycles;
under single-CPU TCG it exceeds 90s. The NetBSD twin (vms_blockdev_netbsd.c)
already caches its backing vnode and reads/writes off it — this is the missing
Linux equivalent.

Fix: a module-global backing-device handle cache (exec_bdev_get_cached /
exec_bdev_cache_release_all in vms_module.c). Each device is opened ONCE
(READ|WRITE, non-exclusive), keyed by dev_t, and reused for every block; the
handles are released together at module exit (vms_exit), the OS-lifetime
analogue of NetBSD's release-at-detach. Slots are only added, never evicted
mid-life, so a handed-back block_device stays valid across the bio (which runs
outside the cache lock) — no use-after-free. A full table or a failed open
returns NULL and the primitives fall back to the original open-per-call path,
so correctness never depends on the cache. Only the OPEN is amortized; every
block is still a real synchronous bio to a real device (INV-6 / Rule 8).

Proof (real /dev/vms, qemu-system-x86_64, TCG, --cpus=1 — the profile that
reproduced the CI failure):
  - baseline 7811bf3 install: FATAL, 7/21 (hung at Configuring)
  - bad-tip  9c507bc install: FATAL, 7/21 (hung at Configuring)
  - THIS fix install:          21/21, full install in 72s
  - THIS fix, full 16-check R1 gate, ALL containers --cpus=1: 16/16 PASS
    (SCSNODE OVMXR1 persists, SYSTEM logs in with the install-set password,
     PRODUCT SHOW + DIRECTORY resolve, USERS home dirs resolve, negctl
     boundary intact). The test is unchanged — not weakened.

NetBSD is unaffected (its backend already caches; the new symbols are
Linux-only). Standalone vms.ko builds+modposts on 6.8 (pre-6.9 branch); the
in-tree bootable module builds+modposts on 6.12 (post-6.9 branch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit b93d141 into main Aug 29, 2026
110 checks passed
@baron-3dl
baron-3dl deleted the work/vms-648-acp-bdev-cache branch August 29, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant