-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
util/memory: warn potential deadlock for Consume in remove (#16987) #18395
util/memory: warn potential deadlock for Consume in remove (#16987) #18395
Conversation
Signed-off-by: ti-srebot <[email protected]>
/run-all-tests |
@SunRunAway, @XuHuaiyu, @Yisaer, @wshwsh12, PTAL. |
@SunRunAway, @XuHuaiyu, @Yisaer, @wshwsh12, PTAL. |
1 similar comment
@SunRunAway, @XuHuaiyu, @Yisaer, @wshwsh12, PTAL. |
LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@wshwsh12, @SunRunAway, @XuHuaiyu, @Yisaer, PTAL. |
1 similar comment
@wshwsh12, @SunRunAway, @XuHuaiyu, @Yisaer, PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
/merge |
Sorry @SunRunAway, you don't have permission to trigger auto merge event on this branch. |
@wshwsh12, @Yisaer, @SunRunAway, @XuHuaiyu, PTAL. |
1 similar comment
@wshwsh12, @Yisaer, @SunRunAway, @XuHuaiyu, PTAL. |
/merge |
Sorry @zz-jason, you don't have permission to trigger auto merge event on this branch. |
@wshwsh12, @Yisaer, @SunRunAway, @XuHuaiyu, PTAL. |
/merge |
/run-all-tests |
cherry-pick #16987 to release-4.0
What problem does this PR solve?
close #16944
Problem Summary:
What is changed and how it works?
What's Changed:
Add a new func
consumeNegative()
which basically does the same thing as Consume(),but it only takes negative value to ensure that no exceed action is triggered.
So the exceed checking is removed.
Replace the original
Consume()
inremove()
withconsumeNegative()
because if exceed action is triggered inConsume()
called byremove()
, then deadlock (one double lock and two conflicting lock order cases) will happen.How it Works:
Exceed Action in
Consume()
called byremove()
will cause deadlock.Besides the double lock in #16944,
I also find two conflicting lock order cases.
Both are related to
Tracker.mu.Lock()
.Case 1:
One mutex is
LogOnExceed.mutex.Lock()
:tidb/util/memory/action.go
Lines 41 to 46 in 2daee41
The other mutex is
LogOnExceed.mutex.Lock()
:tidb/util/memory/tracker.go
Lines 40 to 46 in 2daee41
LogOnExceed.mutex.Lock()
->Tracker.mu.Lock()
LogOnExceed.mutex.Lock()
,t.String()
:tidb/util/memory/action.go
Lines 54 to 61 in 2daee41
Then
t.String()
callst.toString()
.Tracker.mu.Lock()
:tidb/util/memory/tracker.go
Lines 258 to 265 in 2daee41
Tracker.mu.Lock()
->LogOnExceed.mutex.Lock()
Tracker.mu.Lock()
,t.Consume()
:tidb/util/memory/tracker.go
Lines 155 to 163 in 2daee41
tidb/util/memory/tracker.go
Lines 252 to 254 in 2daee41
There is a path that leads to
rootExceed == t
.If that is the case,
Action(rootExceed)
is equal toAction(t)
.tidb/util/memory/tracker.go
Line 221 in 2daee41
Then
Action()
callsLogOnExceed.mutex.Lock()
.tidb/util/memory/action.go
Lines 54 to 56 in 2daee41
Case 2:
Similar to Case 1.
Tracker.actionMu.Lock()
->Tracker.mu.Lock()
Consume()
callsrootExceed.actionMu.Lock()
andAction()
.Action()
callsString()
. ThentoString()
. Thent.mu.Lock()
.Tracker.mu.Lock()
->Tracker.actionMu.Lock()
remove()
callst.mu.Lock()
andt.Consume()
.Then
t.Consume()
callsrootExceed.actionMu.Lock()
.#16944 suggests that we add a new version of
Consume()
without checking exceeding.I agree with this because it warns developers to ensure the input cannot cause exceeding in
Consume()
called byremove()
. Otherwise, a deadlock may happen.This will help prevent future double-lock in #16944 and the conflicting locks in this PR.
Related changes
Check List
Tests
Side effects
No
Release note