@@ -86,11 +86,27 @@ func (solver *networkTopologySolverImpl) PlacePods(
8686 return topologyNodeLessFunc (candidateTopologyNodes [i ], candidateTopologyNodes [j ], true )
8787 })
8888
89- distribution := map [string ]int {}
90- orderedNodes , _ := distributeOfferSlot (jobNetworkRequirements .DesiredOfferSlot , candidateTopologyNodes [0 ], distribution )
89+ for _ , candidate := range candidateTopologyNodes {
90+ distribution := map [string ]int {}
91+ orderedNodes , actualOfferSlot := distributeOfferSlot (jobNetworkRequirements .DesiredOfferSlot , candidate , distribution , jobNetworkRequirements .LayerPodCountMultiple )
92+ if actualOfferSlot >= jobNetworkRequirements .DesiredOfferSlot {
93+ podToNode := distributePods (toSchedulePods , orderedNodes , distribution )
94+ return podToNode , nil
95+ }
96+ }
9197
92- podToNode := distributePods (toSchedulePods , orderedNodes , distribution )
93- return podToNode , nil
98+ var reasons []string
99+ for _ , node := range candidateTopologyNodes {
100+ reasons = append (reasons , fmt .Sprintf ("topology topologyNode %s/%s: %d" , node .Layer , node .Name , node .OfferSlot ))
101+ }
102+ sort .Strings (reasons )
103+ fitError := & framework.FitError {
104+ NumAllNodes : len (nodes ),
105+ Diagnosis : framework.Diagnosis {
106+ NodeToStatusMap : topologyState .NodeToStatusMap ,
107+ },
108+ }
109+ return nil , framework .NewStatus (framework .Unschedulable , fmt .Sprintf (MessageNoCandidateTopologyNodes , jobNetworkRequirements .DesiredOfferSlot , strings .Join (reasons , ";" ), fitError .Error ()))
94110}
95111
96112func (solver * networkTopologySolverImpl ) calculateNodeOfferSlot (
@@ -297,15 +313,23 @@ func distributeOfferSlot(
297313 desiredOfferSlot int ,
298314 topologyNode * networktopology.TreeNode ,
299315 distribution map [string ]int ,
316+ layerPodCountMultiple map [schedulingv1alpha1.TopologyLayer ]int ,
300317) (topologyOrderedNodes []string , offerSlot int ) {
318+ // Calculate the maximum slot this topology node can provide
319+ maxOfferSlot := topologyNode .OfferSlot
320+ if maxOfferSlot > desiredOfferSlot {
321+ maxOfferSlot = desiredOfferSlot
322+ }
323+
324+ if multiple := layerPodCountMultiple [topologyNode .Layer ]; multiple > 1 {
325+ maxOfferSlot = (maxOfferSlot / multiple ) * multiple
326+ }
327+
301328 if topologyNode .Layer == schedulingv1alpha1 .NodeTopologyLayer {
302- offerSlot = topologyNode .OfferSlot
303- if offerSlot > desiredOfferSlot {
304- offerSlot = desiredOfferSlot
305- }
306- distribution [topologyNode .Name ] = offerSlot
307- return []string {topologyNode .Name }, offerSlot
329+ distribution [topologyNode .Name ] = maxOfferSlot
330+ return []string {topologyNode .Name }, maxOfferSlot
308331 }
332+
309333 var children []* networktopology.TreeNode
310334 for _ , child := range topologyNode .Children {
311335 if child != nil {
@@ -315,10 +339,12 @@ func distributeOfferSlot(
315339 sort .Slice (children , func (i , j int ) bool {
316340 return topologyNodeLessFunc (children [i ], children [j ], false )
317341 })
342+
343+ remainingSlot := maxOfferSlot
318344 for _ , child := range children {
319- orderedNodesOfChild , offerSlotOfChild := distributeOfferSlot (desiredOfferSlot , child , distribution )
345+ orderedNodesOfChild , offerSlotOfChild := distributeOfferSlot (remainingSlot , child , distribution , layerPodCountMultiple )
320346 topologyOrderedNodes = append (topologyOrderedNodes , orderedNodesOfChild ... )
321- desiredOfferSlot -= offerSlotOfChild
347+ remainingSlot -= offerSlotOfChild
322348 offerSlot += offerSlotOfChild
323349 }
324350 return topologyOrderedNodes , offerSlot
0 commit comments