Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix two race issues in schedule_queue #81148

Merged
merged 1 commit into from Aug 14, 2019

Conversation

wgliang
Copy link
Contributor

@wgliang wgliang commented Aug 8, 2019

What type of PR is this?

Uncomment only one /kind <> line, hit enter to put that in a new line, and remove leading whitespaces from that line:

/kind api-change

/kind cleanup
/kind design
/kind documentation
/kind failing-test
/kind feature
/kind flake

/kind bug
What this PR does / why we need it:
Run: go test k8s.io/kubernetes/pkg/scheduler/internal/queue --race --count=50

You can get:

WARNING: DATA RACE
Write at 0x00c000386120 by goroutine 39:
  runtime.mapdelete_faststr()
      /usr/local/Cellar/go/1.12.7/libexec/src/runtime/map_faststr.go:297 +0x0
  k8s.io/kubernetes/pkg/scheduler/util.(*heapData).Pop()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/util/heap.go:113 +0x203
  container/heap.Pop()
      /usr/local/Cellar/go/1.12.7/libexec/src/container/heap/heap.go:64 +0xb0
  k8s.io/kubernetes/pkg/scheduler/util.(*Heap).Pop()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/util/heap.go:200 +0x5b
  k8s.io/kubernetes/pkg/scheduler/internal/queue.(*PriorityQueue).flushBackoffQCompleted()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/internal/queue/scheduling_queue.go:356 +0x490
  k8s.io/kubernetes/pkg/scheduler/internal/queue.(*PriorityQueue).flushBackoffQCompleted-fm()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/internal/queue/scheduling_queue.go:334 +0x41
  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152 +0x61
  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153 +0x108
  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait.Until()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 +0x5a

Previous read at 0x00c000386120 by goroutine 38:
  runtime.mapaccess2_faststr()
      /usr/local/Cellar/go/1.12.7/libexec/src/runtime/map_faststr.go:107 +0x0
  k8s.io/kubernetes/pkg/scheduler/util.(*Heap).Get()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/util/heap.go:221 +0x11d
  k8s.io/kubernetes/pkg/scheduler/internal/queue.TestPriorityQueue_AddUnschedulableIfNotPresent_Backoff()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/internal/queue/scheduling_queue_test.go:357 +0xa12
  testing.tRunner()
      /usr/local/Cellar/go/1.12.7/libexec/src/testing/testing.go:865 +0x163

Goroutine 39 (running) created at:
  k8s.io/kubernetes/pkg/scheduler/internal/queue.(*PriorityQueue).run()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/internal/queue/scheduling_queue.go:200 +0xd0
  k8s.io/kubernetes/pkg/scheduler/internal/queue.NewPriorityQueueWithClock()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/internal/queue/scheduling_queue.go:193 +0x9af
  k8s.io/kubernetes/pkg/scheduler/internal/queue.TestPriorityQueue_AddUnschedulableIfNotPresent_Backoff()
      /Users/wangguoliang/Documents/mos/src/k8s.io/kubernetes/pkg/scheduler/internal/queue/scheduling_queue.go:164 +0x70
  testing.tRunner()
      /usr/local/Cellar/go/1.12.7/libexec/src/testing/testing.go:865 +0x163

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

Does this PR introduce a user-facing change?:

NONE

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

NONE

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/bug Categorizes issue or PR as related to a bug. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Aug 8, 2019
@wgliang
Copy link
Contributor Author

wgliang commented Aug 8, 2019

/sig scheduling

@k8s-ci-robot k8s-ci-robot added sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Aug 8, 2019
Copy link
Contributor

@draveness draveness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data race is indeed a problem that we need to solve. But can we have a benchmark number for this change since this one adds a mutex to the important data structure in the scheduler

@wgliang
Copy link
Contributor Author

wgliang commented Aug 8, 2019

The data race is indeed a problem that we need to solve. But can we have a benchmark number for this change since this one adds a mutex to the important data structure in the scheduler

Yes, agree with your comment. I will do it.

@hex108
Copy link
Contributor

hex108 commented Aug 8, 2019

util.Heap is used by queue.PriorityQueue, and operations for PriorityQueue has already been protected by its own lock. It seems that the race is caused by the test case?

@wgliang
Copy link
Contributor Author

wgliang commented Aug 8, 2019

util.Heap is used by queue.PriorityQueue, and operations for PriorityQueue has already been protected by its own lock. It seems that the race is caused by the test case?

From the test results, the two issues are separate.

@hex108
Copy link
Contributor

hex108 commented Aug 8, 2019

We do not need add lock for heap since the user PriorityQueue has lock for it. :)

@wgliang wgliang closed this Aug 8, 2019
@k8s-ci-robot k8s-ci-robot added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Aug 8, 2019
@wgliang wgliang reopened this Aug 8, 2019
@k8s-ci-robot k8s-ci-robot removed the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 8, 2019
@wgliang
Copy link
Contributor Author

wgliang commented Aug 8, 2019

We do not need add lock for heap since the user PriorityQueue has lock for it. :)

I have been tested and found it caused by the test code. Thank you for your reminder.

@wgliang
Copy link
Contributor Author

wgliang commented Aug 8, 2019

@draveness I have modified the code so it seems that I don't need to continue testing the performance data. Thanks.

@draveness
Copy link
Contributor

draveness commented Aug 8, 2019

@draveness I have modified the code so it seems that I don't need to continue testing the performance data. Thanks.

Verified locally, this indeed solves the data race problem in the schedule queue tests. But I'm quite interested in the cause of the data race, the two tests use two different priority queue, it's not supposed to cause the problem, could you explain a little bit to me?

@wgliang
Copy link
Contributor Author

wgliang commented Aug 8, 2019

@draveness I have modified the code so it seems that I don't need to continue testing the performance data. Thanks.

Verified locally, this indeed solves the data race problem in the schedule queue tests. But I'm quite interested in the cause of the data race, the two tests use two different priority queue, it's not supposed to cause the problem, could you explain a little bit to me?

In fact, you can see the reason from the description of the problem(#81148 (comment)): the two tests that are causing the problem are not directly responsible for the race, but they have a relationship with the logic in the main code.

Copy link
Contributor

@hex108 hex108 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

@@ -351,13 +351,15 @@ func TestPriorityQueue_AddUnschedulableIfNotPresent_Backoff(t *testing.T) {
q.AddUnschedulableIfNotPresent(unschedulablePod, oldCycle)
}

q.lock.RLock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to write a function(similar to L109) to wrap the lock and getting pod from podBackoffQ.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I prefer to keep the test simple and verify the data like L358.

@@ -1055,8 +1057,11 @@ func TestHighPriorityFlushUnschedulableQLeftover(t *testing.T) {

addOrUpdateUnschedulablePod(q, &highPod)
addOrUpdateUnschedulablePod(q, &midPod)

q.lock.Lock()
q.unschedulableQ.podInfoMap[util.GetPodFullName(&highPod)].Timestamp = time.Now().Add(-1 * unschedulableQTimeInterval)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addOrUpdateUnschedulablePod already does locking. Instead of applying locking here, I suggest to modify addOrUpdateUnschedulablePod to accept a PodInfo input instead of Pod, therefore you can first create a PodInfo and avoid updating the podInfoMap again (in L1062-1063).

E.g.,
change

func addOrUpdateUnschedulablePod(p *PriorityQueue, pod *v1.Pod) {
	p.lock.Lock()
	defer p.lock.Unlock()
	p.unschedulableQ.addOrUpdate(p.newPodInfo(pod))
}

to

func addOrUpdateUnschedulablePod(p *PriorityQueue, podInfo *framework.PodInfo) {
	p.lock.Lock()
	defer p.lock.Unlock()
	p.unschedulableQ.addOrUpdate(podInfo)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Aug 8, 2019
@wgliang
Copy link
Contributor Author

wgliang commented Aug 12, 2019

/assign @Huang-Wei @bsalamat
PTAL Thanks

@wgliang
Copy link
Contributor Author

wgliang commented Aug 12, 2019

/test pull-kubernetes-kubemark-e2e-gce-big

Copy link
Member

@Huang-Wei Huang-Wei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/approve

Thanks, @wgliang !

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 14, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Huang-Wei, wgliang

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 14, 2019
@k8s-ci-robot k8s-ci-robot merged commit 8c6c94b into kubernetes:master Aug 14, 2019
@k8s-ci-robot k8s-ci-robot added this to the v1.16 milestone Aug 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. release-note-none Denotes a PR that doesn't merit a release note. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants