@@ -226,26 +226,66 @@ func (rsc *service) syncForPods(ctx context.Context, pods []*v1.Pod, gpuGroupToS
226226 return nil
227227}
228228
229- // hasActiveBindRequestsForGpuGroup checks if any non-terminal BindRequests reference
230- // the given GPU group. This prevents premature reservation pod deletion when the
231- // informer cache has not yet propagated GPU group labels on recently-bound fraction pods .
229+ // hasActiveBindRequestsForGpuGroup checks if BindRequests still protect the GPU group.
230+ // A succeeded BindRequest also protects the reservation while its pod is still alive:
231+ // the pod label can lag behind the BindRequest status in the controller cache .
232232func (rsc * service ) hasActiveBindRequestsForGpuGroup (ctx context.Context , gpuGroup string ) (bool , error ) {
233233 bindRequestList := & schedulingv1alpha2.BindRequestList {}
234234 if err := rsc .kubeClient .List (ctx , bindRequestList ); err != nil {
235235 return false , fmt .Errorf ("failed to list BindRequests: %w" , err )
236236 }
237237
238238 for _ , br := range bindRequestList .Items {
239- if br .Status .Phase == schedulingv1alpha2 .BindRequestPhaseSucceeded ||
240- br .Status .Phase == schedulingv1alpha2 .BindRequestPhaseFailed {
239+ if ! slices .Contains (br .Spec .SelectedGPUGroups , gpuGroup ) {
241240 continue
242241 }
243- if slices .Contains (br .Spec .SelectedGPUGroups , gpuGroup ) {
244- return true , nil
242+
243+ if br .Status .Phase == schedulingv1alpha2 .BindRequestPhaseFailed {
244+ continue
245245 }
246+
247+ if br .Status .Phase == schedulingv1alpha2 .BindRequestPhaseSucceeded {
248+ hasLivePod , err := rsc .hasLivePodForBindRequest (ctx , & br )
249+ if err != nil {
250+ return false , err
251+ }
252+ if hasLivePod {
253+ return true , nil
254+ }
255+ continue
256+ }
257+
258+ return true , nil
246259 }
247260 return false , nil
248261}
262+
263+ func (rsc * service ) hasLivePodForBindRequest (ctx context.Context , bindRequest * schedulingv1alpha2.BindRequest ) (bool , error ) {
264+ pod := & v1.Pod {}
265+ err := rsc .kubeClient .Get (ctx , client.ObjectKey {
266+ Namespace : bindRequest .Namespace ,
267+ Name : bindRequest .Spec .PodName ,
268+ }, pod )
269+ if apierrors .IsNotFound (err ) {
270+ return false , nil
271+ }
272+ if err != nil {
273+ return false , fmt .Errorf ("failed to get pod for BindRequest <%s/%s>: %w" ,
274+ bindRequest .Namespace , bindRequest .Name , err )
275+ }
276+
277+ if slices .Contains ([]v1.PodPhase {v1 .PodSucceeded , v1 .PodFailed }, pod .Status .Phase ) {
278+ return false , nil
279+ }
280+
281+ for _ , gpuGroup := range bindRequest .Spec .SelectedGPUGroups {
282+ if slices .Contains (resources .GetGpuGroups (pod ), gpuGroup ) {
283+ return true , nil
284+ }
285+ }
286+
287+ return true , nil
288+ }
249289func (rsc * service ) ReserveGpuDevice (ctx context.Context , pod * v1.Pod , nodeName string , gpuGroup string ) (string , error ) {
250290 logger := log .FromContext (ctx )
251291
0 commit comments