Skip to content

fix(monitor): add missing lock in Observe to prevent data race - #2588

Closed
Rickydama3 wants to merge 5 commits into
Project-HAMi:masterfrom
Rickydama3:fix-vgpu-datarace-v2
Closed

fix(monitor): add missing lock in Observe to prevent data race#2588
Rickydama3 wants to merge 5 commits into
Project-HAMi:masterfrom
Rickydama3:fix-vgpu-datarace-v2

Conversation

@Rickydama3

@Rickydama3 Rickydama3 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?
/kind bug

What this PR does / why we need it:

Disclosure: I used AI to help me track down where the lock was missing, but I wrote and tested the fix myself.

I noticed a data race in vGPUmonitor that causes a panic. Observe() in cmd/vGPUmonitor/feedback.go reads lister.ListContainers() without grabbing the lock, but Update() in cudevshr.go mutates that exact same map via the pod informer.

This just adds lister.Lock() and defer lister.UnLock() to Observe() to fix it, matching how metrics.go safely reads it. I also added a quick test in feedback_test.go to cover the new lines.

Which issue(s) this PR fixes:
Fixes #2573

Special notes for your reviewer:
Nothing special, just a straightforward concurrency fix.

Does this PR introduce a user-facing change?:

None

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Bug Fixes**
  * Improved monitoring reliability by coordinating container-list access during observation and feedback processing.
  * Prevented conflicting updates while monitoring is in progress.
  * Ensured observation completes safely once container-list access becomes available.

* **Tests**
  * Added coverage for container-list locking, blocking behavior, and successful completion after access is released.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Ricky Dama <rickydama2006@gmail.com>
Signed-off-by: Ricky Dama <rickydama2006@gmail.com>
@hami-robot hami-robot Bot added kind/bug Something isn't working dco-signoff: yes labels Aug 11, 2026
@hami-robot
hami-robot Bot requested review from FouoF and archlitchi August 11, 2026 13:48
@hami-robot

hami-robot Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: leodon33
Once this PR has been reviewed and has the lgtm label, please assign shouren for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found 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

@hami-robot hami-robot Bot added the size/S label Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 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: 14d4c855-916e-4435-9281-0c68ffee10db

📥 Commits

Reviewing files that changed from the base of the PR and between 09581a2 and f7a05d0.

📒 Files selected for processing (1)
  • cmd/vGPUmonitor/feedback_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/vGPUmonitor/feedback_test.go

📝 Walkthrough

Walkthrough

Observe now locks the container lister while it reads and updates container state. TestObserve verifies that observation blocks while the lock is held and completes after the lock is released.

Changes

Container observation safety

Layer / File(s) Summary
Lock observation state and validate lock coordination
cmd/vGPUmonitor/feedback.go, cmd/vGPUmonitor/feedback_test.go
Observe locks the container lister and defers unlocking it. TestObserve verifies blocking and completion after lock release.

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

Possibly related issues

Possibly related PRs

  • Project-HAMi/HAMi#2574: Both changes lock the container lister during Observe; this PR also adds a test hook and concurrency test.
  • Project-HAMi/HAMi#2311: Both changes modify container-lister locking for concurrent container access.
  • Project-HAMi/HAMi#2350: Both changes modify cmd/vGPUmonitor/feedback_test.go to test container-lister behavior.

Suggested reviewers: archlitchi

Poem

A rabbit guards the container map,
While Observe follows the lock’s path.
The test waits, then frees the way,
And confirms safe work that day.
🐇 No concurrent writes can make it stray.

🚥 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 describes the added lock in Observe and its purpose of preventing a data race.
Linked Issues check ✅ Passed The changes lock the container lister during Observe and add a concurrency test, addressing issue #2573 objectives.
Out of Scope Changes check ✅ Passed The changes are limited to the Observe locking fix and its supporting test; no unrelated code changes are identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 requested a review from mesutoezdil August 11, 2026 13:49

@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 `@cmd/vGPUmonitor/feedback_test.go`:
- Around line 163-169: Update TestObserve to hold lister.Lock() before invoking
Observe in a goroutine, then verify Observe cannot complete while the lock is
held and does complete after lister.UnLock(). Preserve the empty-lister setup
while making the test assert mutex contention and release behavior.
🪄 Autofix

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: 456f0246-03e9-4323-a741-f28a981cde4d

📥 Commits

Reviewing files that changed from the base of the PR and between 634bf2b and c1fda4b.

📒 Files selected for processing (2)
  • cmd/vGPUmonitor/feedback.go
  • cmd/vGPUmonitor/feedback_test.go

Comment thread cmd/vGPUmonitor/feedback_test.go
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unittests 62.41% <100.00%> (+0.11%) ⬆️

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

Files with missing lines Coverage Δ
cmd/vGPUmonitor/feedback.go 28.40% <100.00%> (+6.98%) ⬆️

... and 6 files with indirect coverage changes

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

Signed-off-by: Ricky Dama <rickydama2006@gmail.com>
@hami-robot hami-robot Bot added size/M and removed size/S labels Aug 11, 2026

@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 `@cmd/vGPUmonitor/feedback_test.go`:
- Around line 179-186: Add a deterministic synchronization hook in the Observe
test flow that signals immediately before the goroutine attempts the lister
lock, and wait for that signal before asserting contention. Replace the fixed
time.After-based readiness assumption around done with this boundary signal,
while retaining the lock-held check so removing lister.Lock() still causes the
test to fail.
🪄 Autofix

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: e7b7ee3c-908a-4551-b375-f7937b5c0b07

📥 Commits

Reviewing files that changed from the base of the PR and between c1fda4b and ec23b35.

📒 Files selected for processing (1)
  • cmd/vGPUmonitor/feedback_test.go

Comment thread cmd/vGPUmonitor/feedback_test.go Outdated
Signed-off-by: Ricky Dama <rickydama2006@gmail.com>
Signed-off-by: Ricky Dama <rickydama2006@gmail.com>

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

left one question inline

if observeTestHook != nil {
observeTestHook()
}
lister.Lock()

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.

issue #2573 says pod add/update informer events call update() at the same time as observe(). this file only registers deletefunc, and that one only logs, it never touches containers. where does the real concurrent write come from today? the lock is still correct and safe to add either way, just checking the reproduction story is accurate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The issue description doesn't quite get the informer events right. Update() and Observe() just run sequentially on the ticker loop, so they don't race with each other.

The real race is between Observe() modifying c.Info in the background and Prometheus concurrently scraping the /metrics endpoint. Since Collect() already grabs the lister lock when responding to Prometheus scrapes, grabbing the same lock in Observe() properly synchronizes the writes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@mesutoezdil I've answered your question inline! Let me know if you need anything else from my end.

if observeTestHook != nil {
observeTestHook()
}
lister.Lock()

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.

pr #2311 hit a real deadlock adding a lock inside listcontainers, because metrics.go already holds the lock when it calls listcontainers. why does this lock here not hit the same issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The issue in #2311 happened because metrics.go already held the lock. When it called ListContainers(), adding a lock inside there made the exact same code try to lock it twice, which causes a deadlock.

The lock here is safe because metrics.go never actually calls Observe(). Observe() only runs in its own separate background loop watchAndFeedback. Since they run totally separate from each other, they just wait their turn for the lock. No double-locking can happen here. @mesutoezdil hope you liked it

@mesutoezdil

Copy link
Copy Markdown
Contributor

This is being closed because it does not comply with the contribution guidelines.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Fatal concurrent map iteration data race in vGPUmonitor feedback observation

2 participants