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

Lock concurrent access to mWpaSupplicant #9704

Merged
merged 2 commits into from
Sep 17, 2021

Conversation

tewarid
Copy link
Contributor

@tewarid tewarid commented Sep 14, 2021

Lock concurrent access to mWpaSupplicant.

Problem

state in GDBusWpaSupplicant may be concurrently accessed by multiples threads leading to race condition.

Change overview

Lock concurrent access to mWpaSupplicant.

Testing

Tested using a custom embedded linux system with all-clusters-app example, and macOS chip-tool for provisioning.

Copy link
Contributor

@mspang mspang left a comment

Choose a reason for hiding this comment

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

Please use a mutex.

@tewarid
Copy link
Contributor Author

tewarid commented Sep 14, 2021

Please use a mutex.

@mspang Please see #9322 (comment) where decision was made with @bzbarsky-apple to use std::atomic. Why is a lock called for in this case?

Code uses std::atomic here under similar circumstance

Code also uses volatile

volatile enum {

@mspang
Copy link
Contributor

mspang commented Sep 14, 2021

Please use a mutex.

@mspang Please see #9322 (comment) where decision was made with @bzbarsky-apple to use std::atomic. Why is a lock called for in this case?

Code uses std::atomic here under similar circumstance

It's not quite the same, but this was probably a mistake.

Code also uses volatile

That doesn't avoid the race except in certain compilers (MSVC) using nonstandard assumptions.

volatile enum {

@tewarid tewarid requested a review from mspang September 15, 2021 12:15
@tewarid tewarid changed the title Declare state in GDBusWpaSupplicant as std::atomic Lock concurrent access to mWpaSupplicant Sep 15, 2021
Copy link
Contributor

@kghost kghost left a comment

Choose a reason for hiding this comment

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

I understand that there can be racing, due to there 2 directions which can go into the class:

  1. From CHIP stack.
  2. From dbus callback.

The better solution can be dispatching the dbus callback back into the chip main thread, so it will be guarded by the chip global lock

Anyway, if this PR resolves the racing problem, there is no reason to block it. But it would be better if leave notes about it, and maybe we can improve it later.

src/platform/Linux/ConnectivityManagerImpl.cpp Outdated Show resolved Hide resolved
@tewarid
Copy link
Contributor Author

tewarid commented Sep 16, 2021

The better solution can be dispatching the dbus callback back into the chip main thread, so it will be guarded by the chip global lock

@kghost Could you please point to an example in the code?

@tewarid
Copy link
Contributor Author

tewarid commented Sep 16, 2021

Please use a mutex.

@mspang Please see #9322 (comment) where decision was made with @bzbarsky-apple to use std::atomic. Why is a lock called for in this case?
Code uses std::atomic here under similar circumstance

It's not quite the same, but this was probably a mistake.

You're right, but don't think it is a mistake - a separate mutex is used to lock critical section.

Code also uses volatile

That doesn't avoid the race except in certain compilers (MSVC) using nonstandard assumptions.

Not a concern of this PR, but does this need to be fixed?

volatile enum {

@tewarid tewarid requested a review from kghost September 16, 2021 11:26
@kghost
Copy link
Contributor

kghost commented Sep 16, 2021

@kghost Could you please point to an example in the code?

I mean that modify the main loop, use a single loop for both chip sdk and d-bus, such that there is only one thread, to prevent the racing.

It won't be an easy change, I need to invest that.

@mspang
Copy link
Contributor

mspang commented Sep 16, 2021

Please use a mutex.

@mspang Please see #9322 (comment) where decision was made with @bzbarsky-apple to use std::atomic. Why is a lock called for in this case?
Code uses std::atomic here under similar circumstance

It's not quite the same, but this was probably a mistake.

You're right, but don't think it is a mistake - a separate mutex is used to lock critical section.

The reasons it was a mistake:

  • Because people will copy it
  • Because atomics are subtle
  • Because relaxed atomics are especially subtle to the extent that the folks who standardized them aren't confident that they can be used safely

Not because it doesn't work or encounters a race condition (it does mean that the load that results in event loop termination does not synchronize-with the thread that stored the termination condition, which is where there is room for controversy). Basically, it's not worth the risk and the controversy. Mutex is a more understandable tool and gives you a real critical section.

Code also uses volatile

That doesn't avoid the race except in certain compilers (MSVC) using nonstandard assumptions.

Not a concern of this PR, but does this need to be fixed?

volatile enum {

@mspang
Copy link
Contributor

mspang commented Sep 16, 2021

Please use a mutex.

@mspang Please see #9322 (comment) where decision was made with @bzbarsky-apple to use std::atomic. Why is a lock called for in this case?
Code uses std::atomic here under similar circumstance

It's not quite the same, but this was probably a mistake.

You're right, but don't think it is a mistake - a separate mutex is used to lock critical section.

The reasons it was a mistake:

  • Because people will copy it
  • Because atomics are subtle
  • Because relaxed atomics are especially subtle to the extent that the folks who standardized them aren't confident that they can be used safely

Not because it doesn't work or encounters a race condition (it does mean that the load that results in event loop termination does not synchronize-with the thread that stored the termination condition, which is where there is room for controversy). Basically, it's not worth the risk and the controversy. Mutex is a more understandable tool and gives you a real critical section.

BTW, I wrote that code, so you can believe me when I say it was a mistake.

Code also uses volatile

That doesn't avoid the race except in certain compilers (MSVC) using nonstandard assumptions.

Not a concern of this PR, but does this need to be fixed?

volatile enum {

@mspang
Copy link
Contributor

mspang commented Sep 16, 2021

Not a concern of this PR, but does this need to be fixed?

volatile enum {

Yes, this code is incorrect and should be fixed, C++11 is the first C++ with a memory model and it did not make volatile a synchronization operation. In fact volatile doesn't have any standard semantics, it's implementation defined what it means.

@mspang mspang merged commit 4198a3c into project-chip:master Sep 17, 2021
@tewarid tewarid deleted the make-state-atomic branch September 17, 2021 11:47
mleisner pushed a commit to mleisner/connectedhomeip that referenced this pull request Sep 20, 2021
* Lock concurrent access to mWpaSupplicant

* Use std::lock_guard to manage std::mutex
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants