-
Notifications
You must be signed in to change notification settings - Fork 2k
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
scheduler: priority inversion problem #7365
Comments
I understand the statement and I agree that this is a problem. |
Thanks for pointing this out, this is indeed a known problem. As you also stated, RIOT does so far move this problem onto the application developers, offering no means of protection against priority inversion inside the core/scheduler. I agree with @gebart here: how about we add the code you provided as a test application (maybe adding some documentation that this test will always fail using RIOTs default kernel configuration). Then based on that, we could look into means we can put (as optional option) into the kernel, to enable e.g. priority inheritance or priority ceiling or similar. |
I gave this some more thought and started to play around a little bit with mutexes, using the example above as 'benchmark' -> see https://github.com/haukepetersen/RIOT/tree/add_core_prioinheritance I thought that there might be an easy solution to integrate priority inheritance into the mutex code, but as I found out, it seems not that easy. The problem I currently look it is caused by mutexes being stacked (e.g. a thread locks more than one at the same time). In the example above this happens implicitly through |
Does a thread have a list of all acquired locks? If so, the priority could be reset to the highest lending priority among locked mutexes. The original thread priority would only have to be registered with the thread. |
nope, that information is not available. But I think I found another way, PR will follow in the next hours... |
Do we have any non-theoretical, real world problem here? Pathfinder was launched twenty years ago. IMO this only gets "solved" (e.g., by priority inversion), because it is actually doable compared to preventing all deadlocks. Why do we solve this (programming error) compared to "thread A locks mutex1, thread B locks mutex2, then A locks mutex 2, then B locks mutex 1 -> classical deadlock"? |
But that doesn't mean, that programming errors like that are not made anymore... And why not give the developer something to his/her hand to make an application potentially more error proof?!
That's for sure! But adding some priority inversion prevention as an optional module would not hurt, right?! |
Having it not only does not hurt, but would be nice. I'm just asking myself if we're solving a problem that noone actually encountered in the wild. So why invest time? (unless it's fun! :) ) |
actually I believe this is encountered quite a bit in the wild and is not something that was a problem only 100 years ago. I think the reason one does not hear about this very often anymore, is that all major real-time OSes do have priority inversion prevention integrated by default/as module... (-> see freertos, zephyr, mynewt, ...). |
I've always been taught priority inheritance as a way to minimize blocking time of higher priority tasks for better real time guarantees. |
Well, I don't. :) Any references to this being a real problem?
True that. Alright, didn't want to discourage fixing this, carry on guys! |
Fixed it, just preparing the PR... |
done #7445 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
This is not a bug, but a design choice. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
Here's a real world case where priority inversion is indeed a problem: #13573 (comment) |
Fixed by #17040 |
The RIOT scheduler seems to have no protection against the priority inversion problem where a task of medium priority can prevent the execution a higher prioritized task when that waits for a resource allocated by a low prioritized task. The attached code example demonstrated this behavior.
A common solution for this is a for this is priority inheritance mechanism, where owning task temporary inherits the priority of the waiting task. But there might be other solutions too.
Even though this problem can be mostly avoided in the application design, it would be an feature which can avoid critical complications and simplifies the design of complex applications.
An famous example for this problem is the Pathfinder Mission which got stuck in a reboot loop (triggered by the watchdog timer) and exceeded its energy budget. In that case, that could be fixed by remotely enabling the priority inheritance feature.
In the example below, the shared resource represented by the mutex res_mtx which is used by a low and a high priority thread. A medium priority thread starts working after 3 s prevents the low priority thread from freeing the mutex and thus, the high priority thread from being scheduled.
The text was updated successfully, but these errors were encountered: