Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 23
Integrate vendor VFIO vGPUs into the instance lifecycle#321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
81c83f1f61e10b8a82ea40624c4d7f92c80cccba0c88e48ad56304a1e4edae0112f2d11e37e1eb97d6807961b45f9794d0ec52366a83a8153686a68028fd4f9db1ed62e5dc059a9130c7a29c9a63ad887641b3b0b34441e250b5702138ad3e6113fd4fc471a05e92637280b74a54afbae54df7ad5c020ddca142e093de5ce5878b89f5e8d3dfcfeb92a5ca9f8c1c45344f75c15feb19720d7bb64fcc51df97a96fc64f62c1abad654a315df27fdda2704bf0336e528930ce96fFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -185,6 +185,63 @@ func configureUFFDGraduationController(cfg *config.Config, instanceManager insta | ||
| }, logger), nil | ||
| } | ||
| func liveInstanceVGPUDevicePaths(ctx context.Context, instanceManager instances.Manager) (map[string]struct{}, time.Duration, error) { | ||
| allInstances, err := instanceManager.ListInstancesForReconcile(ctx) | ||
| if err != nil { | ||
| return nil, 0, err | ||
| } | ||
| protected := make(map[string]struct{}) | ||
| var retryAfter time.Duration | ||
| for _, inst := range allInstances { | ||
| if inst.GPUDevicePath == "" { | ||
| continue | ||
| } | ||
| if inst.HypervisorPID != nil && instances.HypervisorMayBeAlive(inst.HypervisorProcessIdentity, inst.SocketPath) { | ||
| protected[inst.GPUDevicePath] = struct{}{} | ||
| continue | ||
cursor[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| if inst.GPUAssignedAt == nil { | ||
| continue | ||
| } | ||
| remaining := instances.VGPUAssignmentStartupGracePeriod - time.Since(*inst.GPUAssignedAt) | ||
| if remaining <= 0 { | ||
| continue | ||
cursor[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. cursor[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| protected[inst.GPUDevicePath] = struct{}{} | ||
| if retryAfter == 0 || remaining < retryAfter { | ||
| retryAfter = remaining | ||
| } | ||
| } | ||
| return protected, retryAfter, nil | ||
| } | ||
cursor[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| func reconcileVGPUs(ctx context.Context, instanceManager instances.Manager, logger *slog.Logger) { | ||
| protected, retryAfter, err := liveInstanceVGPUDevicePaths(ctx, instanceManager) | ||
| if err != nil { | ||
| // Operator-actionable: vendor VFIO reconciliation stays disabled | ||
| // host-wide (and releases fail closed on the same inventory) until | ||
| // the unreadable instance metadata is repaired. | ||
| logger.Error("failed to list instances for vGPU reconcile protection; reconciling mdev only", "error", err) | ||
| protected = nil | ||
| retryAfter = 0 | ||
| } | ||
cursor[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if err := devices.ReconcileVGPUs(ctx, protected); err != nil { | ||
| logger.Warn("failed to reconcile vGPU devices", "error", err) | ||
| } | ||
| if retryAfter <= 0 { | ||
| return | ||
| } | ||
| go func() { | ||
| timer := time.NewTimer(retryAfter) | ||
| defer timer.Stop() | ||
| select { | ||
| case <-ctx.Done(): | ||
| case <-timer.C: | ||
| reconcileVGPUs(ctx, instanceManager, logger) | ||
| } | ||
| }() | ||
| } | ||
| func run() error { | ||
| startupStarted := time.Now() | ||
| slog.Info("starting hypeman initialization") | ||
| @@ -384,12 +441,9 @@ func run() error { | ||
| return fmt.Errorf("reconcile device state: %w", err) | ||
| } | ||
| // Reconcile mdev devices (clears orphaned vGPUs from previous runs) | ||
| logger.Info("Reconciling mdev devices...") | ||
| if err := devices.ReconcileMdevs(app.Ctx, nil); err != nil { | ||
| // Log but don't fail - mdev cleanup is best-effort | ||
| logger.Warn("failed to reconcile mdev devices", "error", err) | ||
| } | ||
| // Reconcile vGPU devices (clears orphaned vGPUs from previous runs) | ||
| logger.Info("Reconciling vGPU devices...") | ||
| reconcileVGPUs(ctx, app.InstanceManager, logger) | ||
| // Wire up resource validator for aggregate limit checking | ||
| // This enables the instance manager to validate CPU, memory, network, and GPU | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.