diff --git a/pkg/device/ascend/device.go b/pkg/device/ascend/device.go index 7e0765e0da..c4d03ce380 100644 --- a/pkg/device/ascend/device.go +++ b/pkg/device/ascend/device.go @@ -37,12 +37,13 @@ import ( ) const ( - NodeLockAscend = "hami.io/mutex.lock" - Ascend910Prefix = "Ascend910" - Ascend910CType = "Ascend910C" - Ascend910NetworkWeight = 10 - VNPUModeAnnotation = "huawei.com/vnpu-mode" - VNPUModeHamiCore = "hami-core" + NodeLockAscend = "hami.io/mutex.lock" + Ascend910Prefix = "Ascend910" + Ascend910CType = "Ascend910C" + Ascend910NetworkWeight = 10 + VNPUModeAnnotation = "huawei.com/vnpu-mode" + VNPUModeHamiCore = "hami-core" + VNPUNodeSelectorAnnotation = "hami-vnpu-core" ) type Devices struct { @@ -430,16 +431,42 @@ func (npu *Devices) Fit(devices []*device.DeviceUsage, request device.ContainerD originReq := k.Nums prevnuma := -1 klog.InfoS("Allocating device for container request", "pod", klog.KObj(pod), "card request", k) + var tmpDevs map[string]device.ContainerDevices + tmpDevs = make(map[string]device.ContainerDevices) + reason := make(map[string]int) vnpuMode := "" if pod != nil && pod.Annotations != nil { vnpuMode = pod.Annotations[VNPUModeAnnotation] } + + isHAMiCore := (vnpuMode == VNPUModeHamiCore) + + // Verify whether the Node supports hami vnpu core + nodeSupportHamiCore := false + + if nodeInfo != nil && nodeInfo.Node != nil && nodeInfo.Node.Annotations != nil { + nodeSupportHamiCore = nodeInfo.Node.Annotations[VNPUNodeSelectorAnnotation] == "true" + } + + var totalMemPerCard int32 = 0 + if len(devices) > 0 { + totalMemPerCard = devices[0].Totalmem + } + + if request.Memreq > 0 && request.Memreq < totalMemPerCard && request.Nums > 0 { + if !nodeSupportHamiCore && isHAMiCore { + reason[common.ModeNotFit]++ + klog.V(4).InfoS("Node filtered: Node does not support hami-core mode", "node", nodeInfo.Node.Name, "pod", pod.Name) + return false, nil, common.GenReason(reason, len(devices)) + } else if nodeSupportHamiCore && !isHAMiCore { + reason[common.ModeNotFit]++ + klog.V(4).InfoS("Node filtered: Reserved for hami-core but pod is legacy vNPU", "node", nodeInfo.Node.Name, "pod", pod.Name) + return false, nil, common.GenReason(reason, len(devices)) + } + } klog.V(4).InfoS("Fit: vnpu-mode annotation", "pod", pod.Name, "vnpuMode", vnpuMode) - var tmpDevs map[string]device.ContainerDevices - tmpDevs = make(map[string]device.ContainerDevices) - reason := make(map[string]int) needTopology := false if strings.HasPrefix(npu.CommonWord(), Ascend910Prefix) && hasNetworkID(devices) { klog.V(4).Infof("all devices have NetworkID. device CommonWord %s", npu.CommonWord()) @@ -495,7 +522,7 @@ func (npu *Devices) Fit(devices []*device.DeviceUsage, request device.ContainerD } // Set dev.Totalcore to 100 if vnpuMode is hami-core effectiveTotalCore := dev.Totalcore - if vnpuMode == VNPUModeHamiCore { + if isHAMiCore { effectiveTotalCore = 100 } diff --git a/pkg/device/ascend/device_test.go b/pkg/device/ascend/device_test.go index 013c1d6bdf..da7588141c 100644 --- a/pkg/device/ascend/device_test.go +++ b/pkg/device/ascend/device_test.go @@ -1385,14 +1385,15 @@ func TestDevices_Fit(t *testing.T) { devs := InitDevices(config) tests := []struct { - name string - devices []*device.DeviceUsage - request device.ContainerDeviceRequest - annos map[string]string - wantFit bool - wantLen int - wantDevIDs []string - wantReason string + name string + devices []*device.DeviceUsage + request device.ContainerDeviceRequest + annos map[string]string + nodeAnnotation map[string]string + wantFit bool + wantLen int + wantDevIDs []string + wantReason string }{ { name: "fit success", @@ -1776,6 +1777,42 @@ func TestDevices_Fit(t *testing.T) { wantDevIDs: []string{"dev-2", "dev-1"}, wantReason: "", }, + { + name: "fit fail: hami-core pod on legacy node (ModeNotFit)", + devices: []*device.DeviceUsage{{ + ID: "dev-0", Index: 0, Used: 0, Count: 100, + Usedmem: 0, Totalmem: 32768, Totalcore: 100, Usedcores: 0, + Numa: 0, Health: true, + }}, + request: device.ContainerDeviceRequest{ + Nums: 1, Memreq: 15360, MemPercentagereq: 0, Coresreq: 20, + }, + annos: map[string]string{ + VNPUModeAnnotation: VNPUModeHamiCore, + }, + wantFit: false, + wantLen: 0, + wantDevIDs: []string{}, + wantReason: "1/1 ModeNotFit", + nodeAnnotation: map[string]string{}, + }, + { + name: "fit fail: legacy pod on hami-core reserved node (ModeNotFit)", + devices: []*device.DeviceUsage{{ + ID: "dev-0", Index: 0, Used: 0, Count: 100, + Usedmem: 0, Totalmem: 32768, Totalcore: 100, Usedcores: 0, + Numa: 0, Health: true, + }}, + request: device.ContainerDeviceRequest{ + Nums: 1, Memreq: 8738, MemPercentagereq: 0, Coresreq: 0, + }, + annos: map[string]string{}, + wantFit: false, + wantLen: 0, + wantDevIDs: []string{}, + wantReason: "1/1 ModeNotFit", + nodeAnnotation: map[string]string{VNPUNodeSelectorAnnotation: "true"}, + }, } for _, dev := range devs { @@ -1802,6 +1839,11 @@ func TestDevices_Fit(t *testing.T) { } nodeInfo := &device.NodeInfo{ ID: "node1", + Node: &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: test.nodeAnnotation, + }, + }, Devices: map[string][]device.DeviceInfo{ dev.config.CommonWord: { { diff --git a/pkg/device/common/common.go b/pkg/device/common/common.go index 65410143b0..6405dc8dc7 100644 --- a/pkg/device/common/common.go +++ b/pkg/device/common/common.go @@ -37,6 +37,7 @@ const ( NodeUnfitPod = "NodeUnfitPod" NodeFitPod = "NodeFitPod" ResourceQuotaNotFit = "ResourceQuotaNotFit" + ModeNotFit = "ModeNotFit" ) func GenReason(reasons map[string]int, cards int) string {