[Bugfix][KVOffload] Restore evicted CPU blocks and fix cursor advancement - #47235
Draft
Alex-ai-future wants to merge 2 commits into
Draft
Alex-ai-future wants to merge 2 commits into
Alex-ai-future wants to merge 2 commits into
Conversation
Alex-ai-future
requested review from
ApostaC,
WoosukKwon,
alexm-redhat,
heheda12345,
ivanium,
njhill,
orozery,
robertgshaw2-redhat and
ywang96
as code owners
July 1, 2026 02:18
Contributor
Author
…ancement Add CPU eviction tracking to SimpleCPUOffloadScheduler to re-store blocks whose cache entries were lost when CPU blocks are re-allocated, avoiding unnecessary re-prefill for requests with matching prefixes. Resolves the FIXME: num_stored_blocks can be stale and omit evicted blocks in the middle of the request - Add consume_eviction_signal() to BlockPool — atomically reads and resets an eviction flag set by _maybe_evict_cached_block() - Split scanning into Phase 1a (re-scan evicted) + Phase 1b (scan new) - Fix cursor advancement with absolute position semantics - Extract _should_skip_block() helper for reuse between phases Signed-off-by: Alex <alex.tech.lab@outlook.com>
- test_eviction_signal_set_and_consumed: flag lifecycle - test_phase1a_restore_enables_cache_hit: end-to-end cache hit after re-store - test_in_flight_store_protected: in-flight blocks not evicted - test_active_request_blocks_can_be_evicted: active request blocks CAN be evicted Signed-off-by: Alex <alex.tech.lab@outlook.com>
Alex-ai-future
force-pushed
the
fix/cpu-eviction-tracking
branch
from
July 1, 2026 03:08
fbb20b3 to
dcdb332
Compare
Alex-ai-future
marked this pull request as draft
August 24, 2026 07:11
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Add CPU eviction tracking to
SimpleCPUOffloadSchedulerto re-store blocks whosecache entries were lost when CPU blocks are re-allocated, avoiding unnecessary
re-prefill for requests with matching prefixes.
Resolves the FIXME:
num_stored_blocks can be stale and omit evicted blocks in the middle of the requestProblem
When CPU blocks are freed after store completion (
ref_cnt → 0) and laterre-allocated by
get_new_blocks(), their cache entries are removed by_maybe_evict_cached_block(). This can happen while the original request isstill active — CPU and GPU
ref_cnts are independent. Without re-store,subsequent requests with matching prefixes miss the CPU cache and need to
re-prefill.
Solution
Eviction signal: Add
consume_eviction_signal()toBlockPool— atomicallyreads and resets an eviction flag set by
_maybe_evict_cached_block(). Themanager consumes this signal once per step before the request loop.
Phase 1a re-scan: When eviction is detected, re-scan previously stored
blocks (0..already_stored_g) and re-store any that lost their cache entries.
Phase 1b continues to scan newly ready blocks (already_stored_g..ready_blocks_g).
Cursor advancement: Use absolute position semantics — initialize
advanced_per_group[g]toalready_stored_g, Phase 1a does not modify it,Phase 1b adds delta. Final assignment:
state.num_stored_blocks[g] = advanced_per_group[g].Helper extraction: Extract
_should_skip_block()for reuse between phases.Changes
vllm/v1/core/block_pool.py_had_recent_evictionflag andconsume_eviction_signal()methodvllm/v1/simple_kv_offload/manager.py_should_skip_block(); update NOTEtests/v1/simple_kv_offload/test_scheduler.pyImpact
Test Plan
test_eviction_signal_set_and_consumedtest_phase1a_restore_enables_cache_hittest_in_flight_store_protectedtest_active_request_blocks_can_be_evictedTest Result
ruff: All checks passed.
Limitations
from a previous store are re-allocated by
get_new_blocks(), which requireshigh CPU memory pressure or many concurrent stores. When it does occur, Phase 1a
ensures re-store happens.
block_pool.py(signal API) andmanager.py(Phase 1a/1b logic) — the split is intentional as a producer-consumercontract between the two modules.
Alternative approach
If reviewers consider the above limitations too significant for the rare trigger
scenario, an alternative is to document the current eviction behavior as a known
property rather than adding re-store logic:
#47234 — documents CPU
eviction behavior as reference (control branch).