Skip to content

fix(device,plugin): stop MIG usage corruption and fd leak - #2245

Merged
hami-robot[bot] merged 4 commits into
Project-HAMi:masterfrom
adity1raut:fix/mig-usage-accounting-and-fd-leak
Aug 7, 2026
Merged

fix(device,plugin): stop MIG usage corruption and fd leak#2245
hami-robot[bot] merged 4 commits into
Project-HAMi:masterfrom
adity1raut:fix/mig-usage-accounting-and-fd-leak

Conversation

@adity1raut

@adity1raut adity1raut commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

/kind bug

What this PR does / why we need it:

Two independent bugs found while auditing MIG resource accounting in pkg/device/nvidia/device.go and pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go:

  1. Silent MIG usage-accounting corruption for percentage-based memory requests.
    CustomFilterRule checked MIG template/slot sizes against the raw, unresolved request.Memreq. For percentage-based memory requests (MemPercentagereq set, Memreq == 0), that comparison is always trivially true, so the filter could admit a device even when no MIG slot is actually big enough for the real (percentage-resolved) request.
    AddResourceUsage's "fresh template" branch had no guard for the case where no template fits — unlike its sibling ("reuse existing slot") branch, which already returns an error in that case. So if no template fit, the function silently fell through and still incremented Usedmem/Usedcores, corrupting the node's device usage accounting and leaving ContainerDevice.UUID without a valid MIG index suffix.

    Fix: resolve the actual memory request before calling CustomFilterRule (instead of passing the still-zero Memreq), and add the same found-guard to AddResourceUsage's fresh-template branch that the sibling branch already has.

  2. File descriptor leak in createMigApplyLock.
    os.Create(file) returns an open *os.File that was discarded without calling .Close(). This function runs on every ApplyMigTemplate() call (via DisableOtherNVMLOperation), so every MIG reconfiguration on a node leaked one fd.

    Fix: close the file handle after creating it.

Added regression tests:

  • TestAddResourceUsage_MigResetNoFit — verifies AddResourceUsage now returns an error (and doesn't touch usage counters) when no MIG template fits during a fresh template selection.
  • TestFit_MigPercentageRequestRejectsUndersizedTemplate — verifies Fit() now correctly rejects a MIG device whose only template is too small for a percentage-based memory request (this previously passed incorrectly).

Which issue(s) this PR fixes:
Fixes #

Special notes for your reviewer:
Both fixes are minimal and mirror existing patterns already in the file (the found-guard mirrors the sibling branch in AddResourceUsage; the fd close follows normal os.Create usage elsewhere in the codebase).

Does this PR introduce a user-facing change?:

Fix MIG device usage accounting corruption for percentage-based memory requests, and fix a file descriptor leak in the MIG apply lock file creation.

AI Assistance Disclosure: I used Geminy to help investigate the codebase for bugs, diagnose the root cause of both issues, and draft the fix and regression tests. I reviewed, understood, and verified all AI-generated changes (build, tests, lint) before submitting.

Summary by CodeRabbit

  • Bug Fixes

    • Improved MIG resource allocation to report errors when no suitable template is available.
    • Prevented failed allocations from changing usage records or assigning invalid MIG identifiers.
    • Corrected memory filtering for percentage-based resource requests.
    • Improved lock handling so file-closing errors are reported correctly.
  • Tests

    • Added coverage for failed MIG allocations, percentage-based memory requests, and quota configurations.

@hami-robot hami-robot Bot added the kind/bug Something isn't working label Jul 31, 2026
@hami-robot
hami-robot Bot requested a review from archlitchi July 31, 2026 18:05
@hami-robot
hami-robot Bot requested a review from wawa0210 July 31, 2026 18:05
@hami-robot hami-robot Bot added the size/M label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dbbe56a0-7f87-423a-9c4b-94595664e536

📥 Commits

Reviewing files that changed from the base of the PR and between 87d9795 and 16d1b3c.

📒 Files selected for processing (4)
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go
  • pkg/device/nvidia/device.go
  • pkg/device/nvidia/device_test.go
  • pkg/scheduler/webhook_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go
  • pkg/device/nvidia/device.go
  • pkg/device/nvidia/device_test.go

📝 Walkthrough

Walkthrough

The changes propagate lock close errors, preserve MIG allocation state after failed template matching, and apply resolved memory requests during filtering. Webhook quota fixtures now mark configured limits explicitly.

Changes

Lock file handling

Layer / File(s) Summary
Propagate lock close errors
pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go
Lock creation retains the file handle and returns errors from Close.

MIG allocation and filtering

Layer / File(s) Summary
Handle missing MIG templates
pkg/device/nvidia/device.go, pkg/device/nvidia/device_test.go
MIG allocation returns an error when no template fits. Usage increments only after successful allocation. Tests verify unchanged state and container UUID after failure.
Filter resolved memory requests
pkg/device/nvidia/device.go, pkg/device/nvidia/device_test.go
CustomFilterRule receives the resolved memory amount. Tests verify rejection of an undersized MIG template for a percentage-based request.

Quota test fixtures

Layer / File(s) Summary
Mark quota limits as configured
pkg/scheduler/webhook_test.go
Cambricon, MLU, Hygon, and Ascend quota fixtures set LimitSet: true.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested reviewers: mesutoezdil, wawa0210

Poem

A rabbit checks each MIG slot,
And keeps failed counts at the proper plot.
The lock reports close errors clear,
Resolved memory guides each gear.
Configured limits mark the way.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies both main fixes: MIG usage corruption and the file descriptor leak.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/device/nvidia/device.go`:
- Around line 703-705: Move the n.Used increment in AddResourceUsage until after
MIG allocation succeeds, so failed no-fit allocations leave usage unchanged. In
pkg/device/nvidia/device.go lines 703-705, update the allocation flow
accordingly; in pkg/device/nvidia/device_test.go lines 2539-2543, assert that
usage.Used remains 0 after the failed allocation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 525199dc-ba9c-4325-b209-c3be339fdccd

📥 Commits

Reviewing files that changed from the base of the PR and between c7891de and 44ff2b9.

📒 Files selected for processing (3)
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go
  • pkg/device/nvidia/device.go
  • pkg/device/nvidia/device_test.go

Comment thread pkg/device/nvidia/device.go
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unittests 63.45% <100.00%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...vice-plugin/nvidiadevice/nvinternal/plugin/lock.go 59.42% <100.00%> (ø)
pkg/device/nvidia/device.go 97.71% <100.00%> (+0.73%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mesutoezdil mesutoezdil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no ai assistance disclosure is present. if any ai tool was used, it must be disclosed per CONTRIBUTING.md: https://github.com/Project-HAMi/HAMi/blob/master/CONTRIBUTING.md#ai-assistance-notice

Comment thread pkg/device/nvidia/device.go
@adity1raut

Copy link
Copy Markdown
Contributor Author

@archlitchi PTAL This Pr ready to Merged

@archlitchi

Copy link
Copy Markdown
Member

/assign

Comment thread pkg/device/nvidia/device.go Outdated
Two independent bugs found while auditing MIG resource accounting:

1. pkg/device/nvidia/device.go: CustomFilterRule was checking MIG
   template/slot sizes against the raw, unresolved request.Memreq.
   For percentage-based memory requests (MemPercentagereq set,
   Memreq == 0) this comparison is always trivially true, so the
   filter would admit a device even when no MIG slot is actually
   big enough. AddResourceUsage's "fresh template" branch then had
   no guard for that case either: if no template fit, it fell
   through silently and still incremented Usedmem/Usedcores,
   corrupting the node's accounting. Fixed by resolving the actual
   memory request before calling CustomFilterRule, and by adding
   the same found-guard the sibling ("reuse existing slot") branch
   already had.

2. pkg/device-plugin/nvidiadevice/nvinternal/plugin/lock.go: the
   *os.File returned by os.Create in createMigApplyLock was never
   closed, leaking one fd per MIG apply on every ApplyMigTemplate
   call.

Added regression tests for both accounting-corruption paths and
the percentage-based MIG filter check.

Signed-off-by: Aditya Raut <araut7798@gmail.com>
AddResourceUsage incremented n.Used before checking whether a MIG
template/slot actually fit the request, in both the fresh-template and
reuse-slot branches. On a no-fit error, n.Used stayed bumped even
though nothing was allocated, corrupting device usage accounting.

Signed-off-by: Aditya Raut <araut7798@gmail.com>
Project-HAMi#2313 added a LimitSet flag that FitQuota now gates on instead of
Limit != 0, and updated TestFitResourceQuota's fixture accordingly,
but missed three sibling tests in the same file that also build
device.Quota directly: TestFitResourceQuotaNonNvidia,
TestFitResourceQuotaCountsEveryDevice, and
TestFitResourceQuotaAscendMemoryFactor. Their fixtures defaulted to
LimitSet: false, so FitQuota treated the configured limits as unset
and admitted every pod, failing the denial assertions in all three
tests on current master.

Set LimitSet: true on the five affected fixture entries to match what
AddQuota produces, mirroring the fix already applied to
TestFitResourceQuota.

Signed-off-by: Aditya Raut <araut7798@gmail.com>
archlitchi asked for the comments around the CustomFilterRule fix and
its test in device.go/device_test.go to be trimmed to one sentence.

Signed-off-by: Aditya Raut <araut7798@gmail.com>
@adity1raut
adity1raut force-pushed the fix/mig-usage-accounting-and-fd-leak branch from ecf7eac to 16d1b3c Compare August 7, 2026 04:18
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@archlitchi archlitchi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

@hami-robot hami-robot Bot added the lgtm label Aug 7, 2026
@hami-robot

hami-robot Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: adity1raut, archlitchi

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants