Skip to content

fix(detector): fail closed on GPU health check errors - #26

Merged
thxCode merged 5 commits into
mainfrom
fix/nvidia-gsp-failure-reports-healthy
Sep 4, 2026
Merged

fix(detector): fail closed on GPU health check errors#26
thxCode merged 5 commits into
mainfrom
fix/nvidia-gsp-failure-reports-healthy

Conversation

@thxCode

@thxCode thxCode commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

On an 8x H100 node, a card whose GSP firmware stopped answering RPCs (Xid 119 timeout → Xid 154 GPU Reset Required) showed ERR!/N/A telemetry in nvidia-smi, yet gpustack-runtime detect still reported it healthy. The health check is opt-in (GPUSTACK_RUNTIME_DETECT_NO_HEALTH_CHECK defaults to true — unchanged), but even when enabled it was narrow and fail-open: the ECC query sat under a blanket contextlib.suppress, so the very errors a wedged card produces were swallowed and the card reported healthy.

The enabled health check now fails closed on every vendor carrying that pattern: a query the driver errors on reports the device unhealthy, while a query the hardware does not support keeps the previous verdict — no false positives on old drivers or ECC-less cards.

Changes

  • NVIDIA_get_memory_status catches NVMLError explicitly (NVML_ERROR_NOT_SUPPORTED tolerated, anything else unhealthy) and additionally probes NVML_FI_DEV_GET_GPU_RECOVERY_ACTION / NVML_FI_DEV_RESET_STATUS, so a GSP failure that leaves the ECC counters readable still reports unhealthy; an unreadable field falls back to the ECC verdict
  • Iluvatar — extracted _get_memory_status from the two inline checks; ixmlDeviceGetHealth errors fail closed the same way
  • THead — ECC counter query fails closed (HGML_ERROR_NOT_SUPPORTED tolerated)
  • AMD — extracted _get_memory_status; the AMD SMI path decides per err_code (the codeless stub error falls back to ROCm SMI, as the memory read does); the ROCm SMI path tolerates RSMI_STATUS_NOT_SUPPORTED and a missing ECC symbol
  • Docs — the env var docstring and the detector-alignment spec's F1 row record the coverage, and that a query against a wedged card can block until the driver's GSP RPC timeout (up to 45s)

Default behaviour (health check off) is unchanged: no extra driver calls per card per pass.

Verification

  • uv run pytest: 634 passed, 20 skipped; make lint clean
  • 18 new regression tests across the four fake driver bindings; the 8 fail-closed cases were verified red on the pre-fix tree
  • Hardware confirmation (advisory): on a card in the Xid 154 state, GPUSTACK_RUNTIME_DETECT_NO_HEALTH_CHECK=false gpustack-runtime detect should report Status ERR

- replace the blanket suppress in _get_memory_status with an explicit
  catch: tolerate NVML_ERROR_NOT_SUPPORTED, any other NVMLError reports
  the device unhealthy
- probe NVML_FI_DEV_GET_GPU_RECOVERY_ACTION and NVML_FI_DEV_RESET_STATUS
  so a GSP failure (Xid 119/154) that leaves the ECC counters readable
  still reports unhealthy; an unreadable field falls back to the ECC
  verdict
- add regression tests over the fake pynvml, including the fail-closed
  cases that previously reported healthy

Task 1-3 of nvidia-gsp-failure-reports-healthy.

Signed-off-by: thxCode <thxcode0824@gmail.com>
- GPUSTACK_RUNTIME_DETECT_NO_HEALTH_CHECK: with the check on, NVIDIA
  health also covers the driver recovery state (GPU reset required), an
  errored query reports unhealthy, and a query against a wedged device
  can block until the driver's RPC timeout (up to 45s with GSP firmware)
- record the same in the detector-alignment spec's F1 all-vendors row

Task 4 of nvidia-gsp-failure-reports-healthy.

Signed-off-by: thxCode <thxcode0824@gmail.com>
- extract _get_memory_status from the two inline health checks and
  replace the blanket suppress: tolerate NVML_ERROR_NOT_SUPPORTED, any
  other NVMLError from ixmlDeviceGetHealth reports the device unhealthy

Task 5 of nvidia-gsp-failure-reports-healthy.

Signed-off-by: thxCode <thxcode0824@gmail.com>
- replace the blanket suppress in _get_memory_status: tolerate
  HGML_ERROR_NOT_SUPPORTED, any other HGMLError from the ECC counter
  query reports the device unhealthy

Task 6 of nvidia-gsp-failure-reports-healthy.

Signed-off-by: thxCode <thxcode0824@gmail.com>
- extract _get_memory_status from the two inline health checks: an AMD
  SMI ECC error with a genuine status code reports the device unhealthy,
  AMDSMI_STATUS_NOT_SUPPORTED keeps the previous verdict, and the
  codeless stub error falls back to ROCm SMI as the memory read does
- the ROCm SMI path follows the same policy, tolerating
  RSMI_STATUS_NOT_SUPPORTED and a missing ECC symbol

Task 7 of nvidia-gsp-failure-reports-healthy.

Signed-off-by: thxCode <thxcode0824@gmail.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors and improves the device memory health check logic across multiple GPU backends (AMD, Iluvatar, NVIDIA, and THead) to implement a fail-closed policy where genuine driver query errors mark the device as unhealthy, while unsupported queries are tolerated. On NVIDIA, the check is enhanced to also probe the driver's recovery state (such as awaiting reset after a GSP failure). Comprehensive unit tests have been added to verify these behaviors under various failure scenarios. There are no review comments, so I have no feedback to provide.

@thxCode
thxCode merged commit fd62d22 into main Sep 4, 2026
7 checks passed
@thxCode
thxCode deleted the fix/nvidia-gsp-failure-reports-healthy branch September 4, 2026 04: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