-
-
Couldn't load subscription status.
- Fork 2.8k
waker: Fix weak memory issue in wake_by_ref() #7622
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
Conversation
c8bf72a to
186a289
Compare
|
Is it ok to use |
|
No. This is why I said the hardware is not relevant. Even on x86, compiler optimizations are allowed to have the same effect as what you saw on ARM. We need a release op no matter what. |
load(Acquire) might return old value. Previously, when reading waker state got is_notified(), it would return None directly, which could lead to a deadlock in race condition. To prevent this, use an additional CAS with the same value, to ensure we have a Release store pairing with Acquire load in transition_to_running(). tokio-rs#7589
186a289 to
6eb7cfa
Compare
|
The comment has been fixed |
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.
Thanks.
(cherry picked from commit 67869be)
Motivation
When running with Miri, or dated arch like POWER, load(Acquire) might return old value.
But in the branch "COMPLETE || NOTIFIED" which returns None directly, might lead to a deadlock in a race condition.
Example code of deadlock report under Miri can be found in this issue: #7589
Solution
In this PR, use additional CAS with the same value to ensure a happen-before relationship. It will not be necessary on x86, but it's the smallest change, chances that waking the waker concurrently or waking the waker after it's complete might be rare.
An alternative solution might be changing the load to SeqCst, which will prevent Miri from reading old value,
but I am not sure what will happen when fetch_update_action() go to the branch a second time.