Skip to content

Commit 028af09

Browse files
committed
Cut off the cost to run filter plugins when no victim pods are found
If no potential victims could be found, there is no need to evaluate the node again, since its state didn't change. It's safe to return and thus prevent scheduling from running the filter plugins again. NOTE: A node that is filtered out by filter plugins could pass the filter plugins if there is a change on that node, i.e. pods termination on that node. Previously, this could be either caught by the normal `schedule` or `preempt` (pods are terminated when the preemption logic tries to find the nodes and re-evaluate the filter plugins.) Actually, this shouldn't be taken care by the preemption, consider the routine of `schedule` is always running when the interval is "zero", let `schedule` take care of it will release `preempt` from something irrelevant with the `preemption`. Due to above reason, couple of testcase as well as the logic of checking the existence of victim pods are removed as it will never happen after the change. Signed-off-by: Dave Chen <[email protected]>
1 parent 865cbf0 commit 028af09

File tree

2 files changed

+20
-45
lines changed

2 files changed

+20
-45
lines changed

pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,6 @@ func pickOneNodeForPreemption(nodesToVictims map[string]*extenderv1.Victims) str
315315
var minNodes1 []string
316316
lenNodes1 := 0
317317
for node, victims := range nodesToVictims {
318-
if len(victims.Pods) == 0 {
319-
// We found a node that doesn't need any preemption. Return it!
320-
// This should happen rarely when one or more pods are terminated between
321-
// the time that scheduler tries to schedule the pod and the time that
322-
// preemption logic tries to find nodes for preemption.
323-
return node
324-
}
325318
numPDBViolatingPods := victims.NumPDBViolations
326319
if numPDBViolatingPods < minNumPDBViolatingPods {
327320
minNumPDBViolatingPods = numPDBViolatingPods
@@ -488,6 +481,12 @@ func selectVictimsOnNode(
488481
}
489482
}
490483
}
484+
485+
// No potential victims are found, and so we don't need to evaluate the node again since its state didn't change.
486+
if len(potentialVictims) == 0 {
487+
return nil, 0, false
488+
}
489+
491490
// If the new pod does not fit after removing all the lower priority pods,
492491
// we are almost done and this node is not suitable for preemption. The only
493492
// condition that we could check is if the "pod" is failing to schedule due to

pkg/scheduler/framework/plugins/defaultpreemption/default_preemption_test.go

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
323323
expectedNumFilterCalled: 4,
324324
},
325325
{
326-
name: "a pod that would fit on the machines, but other pods running are higher priority",
326+
name: "a pod that would fit on the machines, but other pods running are higher priority, no preemption would happen",
327327
registerPlugins: []st.RegisterPluginFunc{
328328
st.RegisterPluginAsExtensions(noderesources.FitName, noderesources.NewFit, "Filter", "PreFilter"),
329329
},
@@ -334,7 +334,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
334334
st.MakePod().Name("p2").UID("p2").Node("node2").Priority(midPriority).Req(largeRes).Obj(),
335335
},
336336
expected: map[string]*extenderv1.Victims{},
337-
expectedNumFilterCalled: 2,
337+
expectedNumFilterCalled: 0,
338338
},
339339
{
340340
name: "medium priority pod is preempted, but lower priority one stays as it is small",
@@ -380,7 +380,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
380380
},
381381
},
382382
},
383-
expectedNumFilterCalled: 5,
383+
expectedNumFilterCalled: 4,
384384
},
385385
{
386386
name: "mixed priority pods are preempted, pick later StartTime one when priorities are equal",
@@ -404,7 +404,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
404404
},
405405
},
406406
},
407-
expectedNumFilterCalled: 5,
407+
expectedNumFilterCalled: 4, // no preemption would happen on node2 and no filter call is counted.
408408
},
409409
{
410410
name: "pod with anti-affinity is preempted",
@@ -428,9 +428,8 @@ func TestSelectNodesForPreemption(t *testing.T) {
428428
PodAntiAffinityExists("foo", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(),
429429
},
430430
},
431-
"node2": {},
432431
},
433-
expectedNumFilterCalled: 4,
432+
expectedNumFilterCalled: 3, // no preemption would happen on node2 and no filter call is counted.
434433
},
435434
{
436435
name: "preemption to resolve pod topology spread filter failure",
@@ -457,7 +456,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
457456
Pods: []*v1.Pod{st.MakePod().Name("pod-b1").UID("pod-b1").Node("node-b").Label("foo", "").Priority(lowPriority).Obj()},
458457
},
459458
},
460-
expectedNumFilterCalled: 6,
459+
expectedNumFilterCalled: 5, // node-a (3), node-b (2), node-x (0)
461460
},
462461
{
463462
name: "get Unschedulable in the preemption phase when the filter plugins filtering the nodes",
@@ -696,17 +695,6 @@ func TestPickOneNodeForPreemption(t *testing.T) {
696695
},
697696
expected: []string{"node1", "node2"},
698697
},
699-
{
700-
name: "a pod that fits on a machine with no preemption",
701-
registerPlugin: st.RegisterPluginAsExtensions(noderesources.FitName, noderesources.NewFit, "Filter", "PreFilter"),
702-
nodeNames: []string{"node1", "node2", "node3"},
703-
pod: st.MakePod().Name("p").UID("p").Priority(highPriority).Req(largeRes).Obj(),
704-
pods: []*v1.Pod{
705-
st.MakePod().Name("p1").UID("p1").Node("node1").Priority(midPriority).Req(largeRes).StartTime(epochTime).Obj(),
706-
st.MakePod().Name("p2").UID("p2").Node("node2").Priority(midPriority).Req(largeRes).StartTime(epochTime).Obj(),
707-
},
708-
expected: []string{"node3"},
709-
},
710698
{
711699
name: "machine with min highest priority pod is picked",
712700
registerPlugin: st.RegisterPluginAsExtensions(noderesources.FitName, noderesources.NewFit, "Filter", "PreFilter"),
@@ -1088,19 +1076,6 @@ func TestPreempt(t *testing.T) {
10881076
expectedNode: "node1",
10891077
expectedPods: []string{"p1.1", "p1.2"},
10901078
},
1091-
{
1092-
name: "One node doesn't need any preemption",
1093-
pod: st.MakePod().Name("p").UID("p").Priority(highPriority).Req(veryLargeRes).PreemptionPolicy(v1.PreemptLowerPriority).Obj(),
1094-
pods: []*v1.Pod{
1095-
st.MakePod().Name("p1.1").UID("p1.1").Node("node1").Priority(lowPriority).Req(smallRes).Obj(),
1096-
st.MakePod().Name("p1.2").UID("p1.2").Node("node1").Priority(lowPriority).Req(smallRes).Obj(),
1097-
st.MakePod().Name("p2.1").UID("p2.1").Node("node2").Priority(highPriority).Req(largeRes).Obj(),
1098-
},
1099-
nodeNames: []string{"node1", "node2", "node3"},
1100-
registerPlugin: st.RegisterPluginAsExtensions(noderesources.FitName, noderesources.NewFit, "Filter", "PreFilter"),
1101-
expectedNode: "node3",
1102-
expectedPods: []string{},
1103-
},
11041079
{
11051080
name: "preemption for topology spread constraints",
11061081
pod: st.MakePod().Name("p").UID("p").Label("foo", "").Priority(highPriority).
@@ -1170,21 +1145,22 @@ func TestPreempt(t *testing.T) {
11701145
expectedPods: []string{"p1.1", "p1.2"},
11711146
},
11721147
{
1173-
name: "One scheduler extender allows only machine1, but it is not interested in given pod, otherwise node1 would have been chosen",
1148+
name: "One scheduler extender allows only machine1, but it is not interested in given pod, otherwise machine1 would have been chosen",
11741149
pod: st.MakePod().Name("p").UID("p").Priority(highPriority).Req(veryLargeRes).PreemptionPolicy(v1.PreemptLowerPriority).Obj(),
11751150
pods: []*v1.Pod{
1176-
st.MakePod().Name("p1.1").UID("p1.1").Node("node1").Priority(midPriority).Req(smallRes).Obj(),
1177-
st.MakePod().Name("p1.2").UID("p1.2").Node("node1").Priority(lowPriority).Req(smallRes).Obj(),
1178-
st.MakePod().Name("p2.1").UID("p2.1").Node("node2").Priority(midPriority).Req(largeRes).Obj(),
1151+
st.MakePod().Name("p1.1").UID("p1.1").Node("machine1").Priority(midPriority).Req(smallRes).Obj(),
1152+
st.MakePod().Name("p1.2").UID("p1.2").Node("machine1").Priority(lowPriority).Req(smallRes).Obj(),
1153+
st.MakePod().Name("p2.1").UID("p2.1").Node("machine2").Priority(midPriority).Req(largeRes).Obj(),
11791154
},
1180-
nodeNames: []string{"node1", "node2", "node3"},
1155+
nodeNames: []string{"machine1", "machine2"},
11811156
extenders: []*st.FakeExtender{
11821157
{Predicates: []st.FitPredicate{st.Machine1PredicateExtender}, UnInterested: true},
11831158
{Predicates: []st.FitPredicate{st.TruePredicateExtender}},
11841159
},
11851160
registerPlugin: st.RegisterPluginAsExtensions(noderesources.FitName, noderesources.NewFit, "Filter", "PreFilter"),
1186-
expectedNode: "node3",
1187-
expectedPods: []string{},
1161+
// sum of priorities of all victims on machine1 is larger than machine2, machine2 is chosen.
1162+
expectedNode: "machine2",
1163+
expectedPods: []string{"p2.1"},
11881164
},
11891165
{
11901166
name: "no preempting in pod",

0 commit comments

Comments
 (0)