Change:
Which jobs are failing: pull-kubernetes-bazel-test Which test(s) are failing: bazel test //pkg/scheduler/internal/queue:godefaulttest Since when has it been failing: Testgrid link: Reason for failure: WARNING: DATA RACE Read at 0x00c000230db0 by goroutine 47: runtime.mapiterinit() +0x0 (PriorityQueue).flushUnschedulableQLeftover() +0x17a (PriorityQueue).flushUnschedulableQLeftover-fm() +0x41 () +0x61 () +0xce () +0x5a Previous write at 0x00c000230db0 by goroutine 45: runtime.mapassignfaststr() +0x0 (UnschedulablePodsMap).addOrUpdate() +0x30e () +0x601 testing.tRunner() +0x162 Goroutine 47 (running) created at: (PriorityQueue).run() +0x172 () +0xe0b () +0x50 () +0x5a5 testing.tRunner() +0x162 Goroutine 45 (running) created at: testing.(T).Run() +0x659 testing.runTests.func1() +0xa8 testing.tRunner() +0x162 testing.runTests() +0x4ee testing.(M).Run() +0x2ee () bazel-out/k8- +0x2fb Anything else we need to know: I'm very sorry about that. UnschedulablePodsMap is not thread-safe. In , lock will be acquired before operating UnschedulablePodsMap. But in , lock isn‘t be acquired. In the previous case, only a single thread runs so it's ok. But after add goroutine , there will be data race. So I need to acquire lock before operating UnschedulablePodsMap.
/sig testing /sig scheduling

Discussion:
}, } <ins> func addOrUpdateUnschedulablePod(p *PriorityQueue, pod *v1.Pod) { p.lock.Lock() defer p.lock.Unlock() p.unschedulableQ.addOrUpdate(pod) } func getUnschedulablePod(p *PriorityQueue, pod *v1.Pod) *v1.Pod { p.lock.Lock() defer p.lock.Unlock() return p.unschedulableQ.get(pod) } </ins> func TestPriorityQueue_Add(t *testing.T) { q := NewPriorityQueue(nil) if err := q.Add(&medPriorityPod); err != nil {

func TestPriorityQueue_AddIfNotPresent(t *testing.T) { q := NewPriorityQueue(nil) <del> q.unschedulableQ.addOrUpdate(&highPriNominatedPod) </del> <ins> addOrUpdateUnschedulablePod(q, &highPriNominatedPod) </ins> q.AddIfNotPresent(&highPriNominatedPod) // Must not add anything. q.AddIfNotPresent(&medPriorityPod) q.AddIfNotPresent(&unschedulablePod)

if len(q.nominatedPods.nominatedPods["node1"]) != 2 { t.Errorf("Expected medPriorityPod and unschedulablePod to be still present in nomindatePods: %v", q.nominatedPods.nominatedPods["node1"]) } <del> if q.unschedulableQ.get(&highPriNominatedPod) != &highPriNominatedPod { </del> <ins> if getUnschedulablePod(q, &highPriNominatedPod) != &highPriNominatedPod { </ins> t.Errorf("Pod %v was not found in the unschedulableQ.", highPriNominatedPod.Name) } }

if len(q.nominatedPods.nominatedPods) != 1 { t.Errorf("Expected nomindatePods to have one element: %v", q.nominatedPods) } <del> if q.unschedulableQ.get(&unschedulablePod) != &unschedulablePod { </del> <ins> if getUnschedulablePod(q, &unschedulablePod) != &unschedulablePod { </ins> t.Errorf("Pod %v was not found in the unschedulableQ.", unschedulablePod.Name) } }

func TestPriorityQueue_MoveAllToActiveQueue(t *testing.T) { q := NewPriorityQueue(nil) q.Add(&medPriorityPod) <del> q.unschedulableQ.addOrUpdate(&unschedulablePod) q.unschedulableQ.addOrUpdate(&highPriorityPod) </del> <ins> addOrUpdateUnschedulablePod(q, &unschedulablePod) addOrUpdateUnschedulablePod(q, &highPriorityPod) </ins> q.MoveAllToActiveQueue() if q.activeQ.Len() != 3 { t.Error("Expected all items to be in activeQ.")

q := NewPriorityQueue(nil) q.Add(&medPriorityPod) // Add a couple of pods to the unschedulableQ. <del> q.unschedulableQ.addOrUpdate(&unschedulablePod) q.unschedulableQ.addOrUpdate(affinityPod) </del> <ins> addOrUpdateUnschedulablePod(q, &unschedulablePod) addOrUpdateUnschedulablePod(q, affinityPod) </ins> // Simulate addition of an assigned pod. The pod has matching labels for // affinityPod. So, affinityPod should go to activeQ. q.AssignedPodAdded(&labelPod) <del> if q.unschedulableQ.get(affinityPod) != nil { </del> <ins> if getUnschedulablePod(q, affinityPod) != nil { </ins> t.Error("affinityPod is still in the unschedulableQ.") } if _, exists, _ := q.activeQ.Get(affinityPod); !exists { t.Error("affinityPod is not moved to activeQ.") } // Check that the other pod is still in the unschedulableQ. <del> if q.unschedulableQ.get(&unschedulablePod) == nil { </del> <ins> if getUnschedulablePod(q, &unschedulablePod) == nil { </ins> t.Error("unschedulablePod is not in the unschedulableQ.") } }

func TestPriorityQueue_PendingPods(t *testing.T) { q := NewPriorityQueue(nil) q.Add(&medPriorityPod) <del> q.unschedulableQ.addOrUpdate(&unschedulablePod) q.unschedulableQ.addOrUpdate(&highPriorityPod) </del> <ins> addOrUpdateUnschedulablePod(q, &unschedulablePod) addOrUpdateUnschedulablePod(q, &highPriorityPod) </ins> expectedList := []*v1.Pod{&medPriorityPod, &unschedulablePod, &highPriorityPod} if !reflect.DeepEqual(expectedList, q.PendingPods()) { t.Error("Unexpected list of pending Pods for node.")