From fb52250c11bdb5a062e5248394d52b94c31339ea Mon Sep 17 00:00:00 2001 From: MOVZX Date: Wed, 23 Sep 2026 10:00:36 -0400 Subject: [PATCH] [Scheduler] Drop the one-victim preemption guard that upstream #49675 made dead The cascade test now expects zero needless victims. Co-Authored-By: Hinata Signed-off-by: MOVZX --- vllm/v1/core/sched/scheduler.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/vllm/v1/core/sched/scheduler.py b/vllm/v1/core/sched/scheduler.py index e93c0c5e7c..5f17f1e017 100644 --- a/vllm/v1/core/sched/scheduler.py +++ b/vllm/v1/core/sched/scheduler.py @@ -814,6 +814,13 @@ class Scheduler(SchedulerInterface): preempted_req = self.running[-1] # A deferred free will not help with immediate allocation. + # (Upstream #49675. It subsumes our earlier post-hoc guard, + # which stopped after ONE deferred victim: a victim that + # passes this check is freed immediately by + # _preempt_request, so deferred_frees cannot grow below. + # The requester stays running, unscheduled, and retries + # after the fence drains; with every running request in + # flight (PP / async) that is zero victims, not the batch.) if not self._request_blocks_can_be_freed(preempted_req): break @@ -845,7 +852,6 @@ class Scheduler(SchedulerInterface): else: preempted_req = self.running.pop() - num_deferred_before = len(self.deferred_frees) self._preempt_request( preempted_req, scheduled_timestamp, @@ -855,16 +861,6 @@ class Scheduler(SchedulerInterface): if preempted_req == request: # No more request to preempt. Cannot schedule this request. break - if len(self.deferred_frees) > num_deferred_before: - # The ring-skip fix: the victim's blocks are fenced - # behind its in-flight step and return to the pool only - # when that step's output is processed, so retrying the - # allocation now cannot succeed on their account and would - # preempt the next request for nothing -- with every running - # request in flight (PP / async) the whole batch. Stop at one - # deferred victim; this request stays running, unscheduled, - # and retries next step after the drain. - break if new_blocks is None: # Cannot schedule this request.