Skip to content

[GPU Reset 3/3] Add in-process graceful GPU reset (--enable-gpu-reset) - #644

Open
ankitjoju-google wants to merge 5 commits into
GoogleCloudPlatform:masterfrom
ankitjoju-google:gpu-reset-3-reset
Open

ankitjoju-google wants to merge 5 commits into
GoogleCloudPlatform:masterfrom
ankitjoju-google:gpu-reset-3-reset

Conversation

@ankitjoju-google

Copy link
Copy Markdown
Collaborator

GPU Reset, PR 3/3. Depends on PR 1/3 (#642) and PR 2/3 (#643); only the last commit is new here.

Why

Recovering a GPU from a recoverable fault (for example some Xids or a wedged context) currently means rebooting the whole node, which disrupts every workload on it. A GPU reset fixes many of these faults in about a minute and only affects the target GPUs, so it can be tried first, before a reboot.

What

New pkg/gpu/nvidia/reset, enabled with --enable-gpu-reset (default off):

  • Trigger: node label cloud.google.com/perform-gpu-reset=<all|N|N-M-...>.
  • Status: node label cloud.google.com/gpu-reset-status=<code>, JSON details in the annotation cloud.google.com/gpu-reset-status-details, plus node events. The trigger label is cleared when the run ends.
  • Graceful only: the plugin never evicts. Target GPUs are marked unhealthy, then it waits up to 30s for their processes to exit and aborts with Error-GPU-Busy (naming PIDs/pods) if they don't. Each step is undone on abort.
  • Reset: pauses the plugin's own NVML users, runs one nvidia-smi --gpu-reset -i <bdf,...> for all targets, then waits for NVLink fabric, rebuilds MIG/time-sharing state, and restores persistence mode only where it was on.
  • Not supported yet: MPS nodes and forced reset (rejected with Error-Unsupported-Mode).
  • Plugin restarts mid-reset are detected and recovered (Error-Interrupted). Per-phase metrics and logs.

Testing

  • go vet ./..., go test -race ./pkg/gpu/nvidia/... ./cmd/... ./partition_gpu/...
  • GKE hardware (driver 580.178.04):
    • A4 (8x B200): all in ~56s, GPU subset, busy-GPU abort, MIG rebuild, persistence restore, MPS rejection.
    • A4X Max (4x GB300, 2 nodes): all in ~34s; NVLink fabric and multi-node NCCL work after reset; peer node unaffected.

Replaced the deprecated gpu-monitoring-tools library with the official go-nvml library.
Updated method signatures to use raw types for easier testability and mocking, avoiding issues with non-mockable nvml.Device struct.
Updated test cases to match new signatures and smaller mock instance IDs.
- Make Stop() idempotent, synchronize Start()/Stop() with a mutex, and
  wait for background goroutines (listenToEvents, setXIDheartbeat,
  resetXIDConditionWithBackoff) via sync.WaitGroup before freeing the
  NVML event set.
- Keep a single long-lived EventBroadcaster across Stop()/Start() cycles
  instead of attempting an invalid interface assertion in Stop() or
  leaking broadcasters on restart.
- Spawn background goroutines only after NVML device registration
  succeeds, and clean up the allocated eventSet on early Start() failure.
- Restore upstream/master MIG behavior: treat nvml.ERROR_NOT_SUPPORTED
  from GetMigMode() as MIG disabled, verify currentMode == pendingMode,
  and resolve MIG parent UUID and GI/CI IDs via go-nvml handles for
  modern R470+ MIG-<uuid> format with fallback to legacy regex parsing.
- Add unit tests covering idempotent Stop(), Stop()/Start() restart
  without broadcaster leaks, Start() error cleanup, and modern/legacy
  MIG UUID handling.
…el and optimize MIG

- Select on hc.stop when sending to hc.health in catchError so Stop()
  cannot deadlock if the health channel is full or unconsumed during
  teardown.
- Deduplicate physDevice.RegisterEvents calls per physical GPU UUID when
  multiple MIG instances share a parent GPU.
- Skip MIG NVML handle lookups in resolveMigDeviceInfo and
  GPUDevice.parseMigDeviceUUID when the device UUID does not start with
  "MIG-".
- Add TestStopUnderHealthChannelBackpressure and verify single
  RegisterEvents per physical GPU in TestMIGSupportModernAndLegacyUUIDs.
- Extract shared per-GPU MIG partitioning helpers (BuildPartitionStr,
  IsGPUPartitioned, DestroyPartitions, CreatePartitions, DiscoverGPU,
  PartitionIDs) into pkg/gpu/nvidia/mig and update partition_gpu.
- Add PhysicalGPUIDs, MIGDeviceManager, DeviceHealth, UpdateGPUHealth,
  and exported IsMPSHealthy helpers on nvidiaGPUManager.
- Add RefreshDevices on GPUHealthChecker to re-discover MIG instances
  across resets.
- Add Stop/Start/Registerer lifecycle methods on MetricServer and
  ListPodGPUDevices for kubelet PodResources attribution.

BUG=581484470
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