Skip to content

fix(reclaim): isolate evictions per node to prevent ghost evictions#5083

Closed
Aman-Cool wants to merge 1 commit intovolcano-sh:masterfrom
Aman-Cool:fix/reclaim-ghost-eviction
Closed

fix(reclaim): isolate evictions per node to prevent ghost evictions#5083
Aman-Cool wants to merge 1 commit intovolcano-sh:masterfrom
Aman-Cool:fix/reclaim-ghost-eviction

Conversation

@Aman-Cool
Copy link
Copy Markdown
Contributor

What type of PR is this?

Bug fix

What this PR does / why we need it:

reclaimForTask had the same ghost-eviction bug already fixed in normalPreempt.
When reclaim iterates over multiple nodes, evictions were written directly into the
shared statement, so if node A's victims weren't sufficient and we fell through to
node B, both A's and B's evictions would be committed on success, killing pods
unrelated to the final scheduling decision.

The fix mirrors the pattern from normalPreempt: allocate a temporary nodeStmt
per node attempt, discard it if that node doesn't pan out, and merge it into the
outer statement only when the task is actually pipelined to that node.

Which issue(s) this PR fixes:

NONE

Special notes for your reviewer:

The fix is intentionally the same pattern used in normalPreempt — worth
cross-referencing that code path when reviewing. A regression test is included
that sets up two nodes where only one can satisfy the preemptor, asserting only
that node's victim gets evicted.
-->

NONE

Copilot AI review requested due to automatic review settings March 5, 2026 07:16
@volcano-sh-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign k82cn 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

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical bug in the reclaimForTask function within the scheduler, which previously led to "ghost evictions." The issue arose when the scheduler attempted to reclaim resources across multiple nodes; if a node failed to satisfy the scheduling requirements after evicting pods, those evictions would still be committed. The fix introduces a mechanism to isolate eviction operations per node using temporary statements, ensuring that evictions are only finalized when a task is successfully scheduled onto that node. This significantly enhances the reliability and correctness of the resource reclamation process.

Highlights

  • Bug Fix: Addressed a "ghost-eviction" bug in reclaimForTask where pods could be evicted unnecessarily if reclaim failed on a node after initial evictions were recorded.
  • Isolation of Evictions: Implemented a per-node temporary statement (nodeStmt) to isolate eviction operations, ensuring that evictions are only committed if a task is successfully pipelined to that specific node.
  • Pattern Mirroring: The fix mirrors the pattern already established in normalPreempt for handling eviction statements, promoting consistency in the codebase.
  • Regression Test: Included a new test case to validate that only victims from the successfully reclaimed node are evicted, preventing unintended evictions.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • pkg/scheduler/actions/reclaim/reclaim.go
    • Introduced nodeStmt to manage evictions locally for each node attempt.
    • Updated Evict and Pipeline calls to use nodeStmt instead of the shared stmt.
    • Added logic to Discard nodeStmt if pipeline fails or resources are insufficient, and Merge it into the main stmt on success.
  • pkg/scheduler/actions/reclaim/reclaim_test.go
    • Added a new test case named "only evict victims from the node where reclaim actually succeeds" to verify the per-node eviction isolation.
Activity
  • No human activity (comments, reviews, etc.) has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@volcano-sh-bot volcano-sh-bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Mar 5, 2026
@Aman-Cool Aman-Cool force-pushed the fix/reclaim-ghost-eviction branch from ef3cf45 to fbad6ec Compare March 5, 2026 07:17
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

Code Review

The pull request successfully addresses the 'ghost-eviction' bug in reclaimForTask by introducing a temporary nodeStmt for each node attempt. This ensures that eviction operations are isolated and only committed if the task is successfully pipelined to the respective node, correctly managing their lifecycle using temporary Statement objects. The implementation is consistent with the pattern used in normalPreempt and is thoroughly validated by a new, detailed regression test case. No critical, high, or medium severity vulnerabilities were detected in the modified code. These changes enhance the correctness and reliability of the reclaim logic.

@Aman-Cool Aman-Cool force-pushed the fix/reclaim-ghost-eviction branch from fbad6ec to e568ccf Compare March 5, 2026 07:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a reclaim-path bug where eviction operations could “leak” across node attempts, causing pods on earlier (failed) nodes to be evicted when reclaim ultimately succeeds on a later node.

Changes:

  • Introduce a per-node temporary Statement (nodeStmt) in reclaimForTask, discarding it on failure and merging it into the outer statement only on success.
  • Add a regression test intended to ensure only victims from the successful node are evicted.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
pkg/scheduler/actions/reclaim/reclaim.go Isolates evictions/pipeline ops per node attempt via nodeStmt, merging only on successful pipeline.
pkg/scheduler/actions/reclaim/reclaim_test.go Adds a regression test case for preventing “ghost evictions” in reclaim.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +270 to +279
// n1: 1 CPU total, fully used by victim-n1 (1 CPU, q1, preemptable).
// FutureIdle=0; 0+1=1 < 2 → ValidateVictims fails → n1 skipped entirely.
// n2: 3 CPU total, 1 CPU idle + victim-n2 (2 CPU, q1, preemptable).
// FutureIdle=1; 1+2=3 ≥ 2 → ValidateVictims passes → reclaim succeeds.
//
// Expected: only victim-n2 is evicted. victim-n1 must NOT be evicted.
//
// Before the nodeStmt fix, evictions went directly into the outer Statement
// without per-node isolation, so evictions from nodes that are later skipped
// or fail could leak into stmt.Commit(). The nodeStmt pattern prevents this.
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

This regression test’s setup has n1 failing ValidateVictims before any eviction is attempted, so it won’t reproduce the historical “ghost eviction” leak (which requires evictions to be recorded for a node attempt that later fails/gets skipped). To actually validate the per-node statement isolation, make the first node attempt perform at least one successful Evict and then fail to pipeline (e.g., via a small test plugin/event handler that injects an AllocateFunc error for n1) before succeeding on n2, and assert only n2’s victim is committed.

Copilot uses AI. Check for mistakes.
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.

will have a look🥲

@Aman-Cool Aman-Cool force-pushed the fix/reclaim-ghost-eviction branch from 53d6343 to 16576a4 Compare March 5, 2026 07:25
@volcano-sh-bot volcano-sh-bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed do-not-merge/contains-merge-commits size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 5, 2026
@Aman-Cool Aman-Cool force-pushed the fix/reclaim-ghost-eviction branch from 16576a4 to 4491921 Compare March 5, 2026 07:26
@volcano-sh-bot volcano-sh-bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 5, 2026
@Aman-Cool Aman-Cool force-pushed the fix/reclaim-ghost-eviction branch 2 times, most recently from d59c822 to 204b632 Compare March 5, 2026 07:39
@Aman-Cool
Copy link
Copy Markdown
Contributor Author

@hajnalmt @hzxuzhonghu @JesseStutler,I noticed reclaimForTask had the same ghost-eviction issue previously fixed in normalPreempt, so this PR applies the same per-node eviction pattern here. The change is fairly small, would really appreciate a quick review when you get a moment. Thanks!

Copy link
Copy Markdown
Member

@hajnalmt hajnalmt left a comment

Choose a reason for hiding this comment

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

/hold

This PR doesn't make any sense to me.
You are undoing some changes in #5067 and create a bad nodeStmt that will panic?
Have you accidentally created the same PR twice?

@volcano-sh-bot volcano-sh-bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 5, 2026
Use a temporary nodeStmt per node attempt in reclaimForTask so that
evictions are only committed when reclaim succeeds on that node.
On failure the nodeStmt is discarded, preventing ghost evictions of
victims from nodes that were never used.

Add regression test verifying only the successful node's victims
are evicted when multiple nodes are attempted.

Signed-off-by: Aman-Cool <aman017102007@gmail.com>
@Aman-Cool
Copy link
Copy Markdown
Contributor Author

Was working on this in parallel🥲, #5067 got merged while I had this in progress. Closing.
Happy belated Holi btw🥳!!!

@Aman-Cool Aman-Cool closed this Mar 5, 2026
@Aman-Cool Aman-Cool deleted the fix/reclaim-ghost-eviction branch March 5, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants