From 14e4e9828f77e96eb8a47b8263e5114b1d810fbf Mon Sep 17 00:00:00 2001 From: Eshiv Pandey Date: Fri, 31 Jul 2026 21:10:41 +0530 Subject: [PATCH] fix(ascend): skip unhealthy devices in Fit() The Ascend device plugin writes Health: false into node annotations when GetDeviceHealth() reports an unhealthy NPU. The scheduler decodes this and buildNodeUsage() copies it to DeviceUsage.Health. However, ascend.Fit() never checked dev.Health, allowing unhealthy NPUs to remain eligible for allocation. Add a dev.Health check at the top of the device loop, mirroring the existing nvidia.Fit() pattern. Unhealthy devices are skipped with reason CardNotHealth. Signed-off-by: Eshiv Pandey --- pkg/device/ascend/device.go | 5 +++++ pkg/device/ascend/device_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/pkg/device/ascend/device.go b/pkg/device/ascend/device.go index 5ded69125d..e824f4c29e 100644 --- a/pkg/device/ascend/device.go +++ b/pkg/device/ascend/device.go @@ -473,6 +473,11 @@ func (npu *Devices) Fit(devices []*device.DeviceUsage, request device.ContainerD dev := v klog.V(4).InfoS("scoring pod", "pod", klog.KObj(pod), "device", dev.ID, "Memreq", k.Memreq, "MemPercentagereq", k.MemPercentagereq, "Coresreq", k.Coresreq, "Nums", k.Nums, "device index", i) + if !dev.Health { + reason[common.CardNotHealth]++ + klog.V(5).InfoS(common.CardNotHealth, "pod", klog.KObj(pod), "device", dev.ID, "health", dev.Health) + continue + } _, found, numa := npu.checkType(pod.GetAnnotations(), *dev, k) if !found { reason[common.CardTypeMismatch]++ diff --git a/pkg/device/ascend/device_test.go b/pkg/device/ascend/device_test.go index ab2fac6c54..85c7394f48 100644 --- a/pkg/device/ascend/device_test.go +++ b/pkg/device/ascend/device_test.go @@ -2029,6 +2029,32 @@ func TestDevices_Fit(t *testing.T) { wantDevIDs: []string{}, wantReason: "1/1 ExclusiveDeviceAllocateConflict", }, + { + name: "fit fail: CardNotHealth", + devices: []*device.DeviceUsage{{ + ID: "dev-0", + Index: 0, + Used: 0, + Count: 100, + Usedmem: 0, + Totalmem: 1280, + Totalcore: 100, + Usedcores: 0, + Numa: 0, + Health: false, + }}, + request: device.ContainerDeviceRequest{ + Nums: 1, + Memreq: 512, + MemPercentagereq: 0, + Coresreq: 50, + }, + annos: map[string]string{}, + wantFit: false, + wantLen: 0, + wantDevIDs: []string{}, + wantReason: "1/1 CardNotHealth", + }, } for _, dev := range devs {