-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
pm: device_runtime: Use its own queue #87496
base: main
Are you sure you want to change the base?
Conversation
@bjarki-andreasen thanks for pointing this problem out |
Device runtime is using the system workqueue to do operations that are mostly blockers (suspend a device). This should not happen. This commit defines a queue for the device runtime async operations. The test for this API was assuming that the system workqueue priority (which is cooperative) so we need to change the test priority to be lower than the device runtime workqueue priority. Signed-off-by: Flavio Ceolin <flavio@hubblenetwork.com>
2d0a7ec
to
71ed1f3
Compare
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.
Really nice!
Should this be optional? Asynchronous PM is not necessarily used at all in an application, but this will incur the additional thread regardless. I'm really not a fan of these "one job" workqueues. What is the use case that triggered this change? |
Async will become optional as well. A usecase that triggered this change is the modem subsystem, which is async, and build around the system workqueue. The work queue is not allowed to be blocking, otherwise it can't be shared, work has to be async. A design decision that triggered the change is simply that no blocking API may be called from a shared work queue, so pretty much all device driver APIs and pm actions are not allowed. |
Hard disagree on this one, Bluetooth tried to enforce such a black and white rule and it caused many problems, see #84282. |
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.
Should this be optional? Asynchronous PM is not necessarily used at all in an application, but this will incur the additional thread regardless. I'm really not a fan of these "one job" workqueues. What is the use case that triggered this change?
I am not a fan either. The reason that triggered it is what @bjarki-andreasen explained. There is a resource penalty in having its own queue but make this code less error prone, to minimize the drawbacks I plan to make it optional (async support) since a lot of applications may not need it.
The system work queue is serviced by a single thread. It can only execute one work item at a time. If item "a" blocks until item "b" is executed, item "b" is never executed. Since any module can use the sys work queue internally, there is no guarantee that item "a" will not end up blocked by item "b". If the above statement is correct, there is nothing to disagree with, it simply can't be used safely with blocking APIs. I will create a PR to add this to the docs. We can discuss from there :) |
@JordanYates There is an entry in the docs here warning about the deadlock https://docs.zephyrproject.org/latest/kernel/services/threads/workqueue.html#work-item-lifecycle: "A handler function can use any kernel API available to threads. However, operations that are potentially blocking (e.g. taking a semaphore) must be used with care, since the workqueue cannot process subsequent work items in its queue until the handler function finishes executing." Its not that strongly worded, "must be used with care" is essentially what I'm referring to. Calling A user has no way of knowing why calling a pm device API on a particular device suddenly makes seemingly random parts of the system stop responding, its a particularly unintuitive behavior which is really hard to narrow down. |
PR for documenting and asserting safe use of system work queue #87522 |
can this be made a choice, i.e a choice between using system workq and a dedicated workq? This way, depending on the application and resources available you can use existing system workq or have one dedicated for PM if system workq become crowded with blocking consumers and you are able to afford another thread? |
it can be done. There is possible issues associated with this but we can make it optional with default to have its own queue. |
Not safely, it breaks drivers which use the system workqueue internally. Its not a question of "crowded", its a question of deadlocking :) |
Device runtime is using the system workqueue to do operations that are mostly blockers (suspend a device). This should not happen.
This commit defines a queue for the device runtime async operations.
The test for this API was assuming that the system workqueue priority (which is cooperative) so we need to change the test priority to be lower than the device runtime workqueue priority.