You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@yunikorn.apache.org by "weichen lai (Jira)" <ji...@apache.org> on 2026/09/06 13:23:00 UTC
[jira] [Created] (YUNIKORN-3445) [Core] SortAllocationsBasedOnAsk prioritizes originator and opted-out pods for preemption instead of protecting them
weichen lai created YUNIKORN-3445:
-------------------------------------
Summary: [Core] SortAllocationsBasedOnAsk prioritizes originator and opted-out pods for preemption instead of protecting them
Key: YUNIKORN-3445
URL: https://issues.apache.org/jira/browse/YUNIKORN-3445
Project: Apache YuniKorn
Issue Type: Bug
Components: core - scheduler
Affects Versions: 1.9.0
Reporter: weichen lai
Assignee: weichen lai
h3. Overview
In {{pkg/scheduler/objects/preemption_utilities.go}}, {{SortAllocationsBasedOnAsk()}} and {{scoreAllocationBasedOnAsk()}} determine victim ordering during preemption.
Under the current implementation, allocations with {{!allowPreemptSelf}} (opted-out) or {{isOriginator}} (driver/manager) receive higher-order score bits ({{scoreNoPreempt}} = {{1 << 34}}, {{scoreOriginator}} = {{1 << 33}}):
{code:go}func scoreAllocationBasedOnAsk(allocation *Allocation, ask *resources.Resource) uint64 {
var score uint64 = 0
if allocation.IsOriginator() {
score |= scoreOriginator // 1 << 33
}
if !allocation.IsAllowPreemptSelf() {
score |= scoreNoPreempt // 1 << 34
}
score += allocation.GetAllocatedResource().TypeMatching(ask)
return score
}
{code}
Because {{SortAllocationsBasedOnAsk()}} orders allocations in descending order ({{scoreLeft > scoreRight}}), opted-out and originator allocations receive higher scores and are placed at the beginning of the candidate slice rather than at the end.
h2.
h3. Comparison with Design Documentation
This ordering conflicts with documented design specifications:
* **Preemption Law #1 (preemption policies are strong suggestions, not guarantees):** Opting out of preemption and originator status are intended as a last resort when no other suitable allocations can be preempted.
* **Quota Preemption Design Document:** The specification states that non-originators and pods with {{allowPreemption: true}} should receive higher scores to prioritize regular allocations for preemption over originators and opted-out pods.
h2.
h3. Test Verification
The following test demonstrates the ordering in {{pkg/scheduler/objects/preemption_utilities_test.go}}:
{code:go}func TestSortAllocationsBasedOnAsk_PreemptionOrdering(t *testing.T) {
node := NewNode(&si.NodeInfo{
NodeID: "node1",
SchedulableResource: &si.Resource{
Resources: map[string]*si.Quantity{"first": {Value: 100}},
},
})
res := resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10})
total := resources.NewResourceFromMap(map[string]resources.Quantity{"first": 100})
ask := resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10})
regularPod := createAllocation("regularPod", "app1", node.NodeID, true, false, 10, false, res)
originatorPod := createAllocation("originatorPod", "app1", node.NodeID, true, true, 10, false, res)
optedOutPod := createAllocation("optedOutPod", "app1", node.NodeID, false, false, 10, false, res)
allocations := []*Allocation{regularPod, originatorPod, optedOutPod}
SortAllocationsBasedOnAsk(allocations, total, ask)
// Current ordering:
// allocations[0]: optedOutPod
// allocations[1]: originatorPod
// allocations[2]: regularPod
//
// Expected ordering per design: regularPod should be placed at index 0
assert.Equal(t, allocations[0].GetAllocationKey(), "regularPod",
"Expected regularPod at index 0, but got: %s", allocations[0].GetAllocationKey())
}
{code}
*Output:*
{code}=== RUN TestSortAllocationsBasedOnAsk_PreemptionOrdering
preemption_utilities_test.go:320: Expected regularPod at index 0, but got: optedOutPod
--- FAIL: TestSortAllocationsBasedOnAsk_PreemptionOrdering (0.00s)
{code}
h2.
h3. Impact
During Quota Preemption, reducing a queue's quota results in originator and opted-out allocations being preempted before standard worker allocations.
h2.
h3. Proposed Solution
In {{pkg/scheduler/objects/preemption_utilities.go}}, assign the higher-order score bits to unprotected allocations ({{allowPreemptSelf == true}} and {{!isOriginator}}):
{code:go}const (
scoreAllowPreempt uint64 = 1 << 34
scoreNonOriginator uint64 = 1 << 33
)
func scoreAllocationBasedOnAsk(allocation *Allocation, ask *resources.Resource) uint64 {
var score uint64 = 0
if !allocation.IsOriginator() {
score |= scoreNonOriginator
}
if allocation.IsAllowPreemptSelf() {
score |= scoreAllowPreempt
}
score += allocation.GetAllocatedResource().TypeMatching(ask)
return score
}
{code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@yunikorn.apache.org
For additional commands, e-mail: dev-help@yunikorn.apache.org