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

core: add priority inheritance option #7445

Closed

Conversation

haukepetersen
Copy link
Contributor

@haukepetersen haukepetersen commented Aug 4, 2017

This PR allows the scheduler to enable priority inheritance when dealing with critical sections, which is a default way to prevent priority inversion (-> see #7365 and related #7444, #7372).

To enable the use of priority inheritance, just build RIOT adding the core_priority_inheritance pseudo module.

Just to give a first idea about the memory impact: enabling this module for gnrc_networking on the samr21-xpro adds 36b RAM and 184b ROM to the build. So this comes indeed not for free...

EDIT:
Our of offline discussion with @kaspar030 and by thinking about it, I came to the conclusion, that mutexes and msg_send_receive() are the only two things in the kernel that model something like critical sections and where it makes sense to inherit priorities. So I extended this PR also to cover msg_send_receive().

@haukepetersen haukepetersen added Area: core Area: RIOT kernel. Handle PRs marked with this with care! Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Type: new feature The issue requests / The PR implemements a new feature for RIOT CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Aug 4, 2017
@haukepetersen haukepetersen added this to the Release 2017.10 milestone Aug 4, 2017
@kaspar030
Copy link
Contributor

Nice!

This PR allows the scheduler to enable priority inheritance when dealing with critical sections,

please add that "critical sections" in this case means "mutexes".

@haukepetersen
Copy link
Contributor Author

didn't want to add that (yet), as I think I can also do it easily for msg_send_recv in the next 30 min or so :-)

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
* 2013, 2014 Freie Universität Berlin
* 2013 - 2017 Freie Universität Berlin
Copy link
Member

Choose a reason for hiding this comment

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

please keep spacing consistent in the license header (I prefer without spaces and it seems to be the goto in the code base)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yepp, I'll remove them

@jnohlgard
Copy link
Member

Nice that you are tackling this issue, @haukepetersen!

@haukepetersen
Copy link
Contributor Author

fixed some minor things and added priority inheritance to msg_send_receive().

@bergzand
Copy link
Member

bergzand commented Aug 6, 2017

Might be just an edge case, but does this work as intended when there are two partially overlapping critical sections, such that:

  1. Mutex A locks
  2. Mutex B locks
  3. Mutex A unlocks
  4. Mutex B unlocks

Assuming that there are two other higher priority threads waiting on A and B respectively.
As far as I can see, the unlock of A would restore the priority to the original priority of the thread instead of the priority needed to prevent priority inversion for mutex B.

If this is an issue, I would not consider this blocking, this solution is better than the current situation.

@haukepetersen
Copy link
Contributor Author

Yes, on first sight this actually does seem like an issue. I will create a test case later today to make sure. And though I think this scenario can be constructed artificially, I wonder if this situation does actually occur in 'normal' code sequences?

@haukepetersen
Copy link
Contributor Author

test created in #7455

@bergzand
Copy link
Member

bergzand commented Aug 8, 2017

To be honest, I don't think it is necessary to take the overlapping mutex scenario into account. I think it is good to have somewhere some documentation that it does not work for overlapping mutexes, but a fix for cleanly nested mutexes should be enough in most situations. Then, if somebody ever manages to trigger this scenario, it is at least possible to extend one of the critical sections to build a nested structure.

@haukepetersen
Copy link
Contributor Author

I agree. Though I think the test application for that does not hurt, useful for documentation as well as future tracking (maybe someone at some point comes up with an efficient working solution to that problem as well...).

So how do we proceed with this PR? I would suggest that we need at least two very thorough reviews. Also I guess I need to write some comprehensive documentation. And last we need some more code size analysis to make sure that this PR does not change anything if the core_priority_inheritance module is not included. Do you guys agree with this?

@travisgriggs
Copy link
Contributor

Long term, will there be any reason to not ALWAYS have priority inheritance turned on? Any other industrial RTOS I've noticed that brags about this, doesn't offer it as an option, instead it just claims it does it.

@jnohlgard
Copy link
Member

I agree with @travisgriggs, priority inheritance should be a default feature of the kernel.

@haukepetersen
Copy link
Contributor Author

There is one important reason: memory usage. Priority inheritance adds noticeable memory overheads when used, so enabling this per default in RIOT (where many applications don't even have need for real-time features) is at least debatable... The question is is guess: do we per default want many features in that can be disabled when optimizing for memory usage, or do we want a very slim default system and users enable the features they want to have. I tend to the latter here!

@OlegHahm
Copy link
Member

OlegHahm commented Oct 3, 2017

@haukepetersen, @kaspar030, couldn't one argue that the same is true for the current IPC (core_msg) which is built-in per default AFAIK.

@bergzand
Copy link
Member

bergzand commented Oct 4, 2017

I would argue for enabling this module by default. Mainly because of usability. I think it is a lot easier to disable this module when a developer is certain that he really doesn't need it and he does need the memory footprint reduction, than to have to debug scheduling issues until the developer finds out that PIP is not enabled.

This might sound a bit exaggerated. What I want to say is that it is probably easier to slim down a RIOT build by removing modules you're certain you don't need than it is to hunt down issues due to modules you did have to enable explicitly (even more so with scheduling issues).

@jnohlgard
Copy link
Member

I agree with @bergzand regarding enabling this module by default.

@haukepetersen
Copy link
Contributor Author

couldn't one argue that the same is true for the current IPC (core_msg)

Yes, and I would tend to disable this by default, also :-)

@travisgriggs
Copy link
Contributor

I don't care whether it's modular or not, but... I believe this should be bound to the "prioritized threads" module. It's an inherit issue with prioritized threads. A module which adds "threads with priorities" should include this behavior.

@OlegHahm
Copy link
Member

OlegHahm commented Oct 4, 2017

I also tend to agree with @bergzand. Disabling features that are not always needed (e.g., IPC) seems legit since a developer will easily figure out that he needs this feature. Disabling certain properties of the kernel may become much harder to detect.

@haukepetersen
Copy link
Contributor Author

rebased on top of #7444 and #9306 and enabled the core_priority_inheritance module per default

Starting to address comments next

@haukepetersen
Copy link
Contributor Author

addressed some of the comments, will continue tomorrow.

@kaspar030
Copy link
Contributor

enabled the core_priority_inheritance module per default

Maybe save for another PR?

@kaspar030
Copy link
Contributor

enabled the core_priority_inheritance module per default

Let me elaborate on this.

Long term, will there be any reason to not ALWAYS have priority inheritance turned on? Any other industrial RTOS I've noticed that brags about this, doesn't offer it as an option, instead it just claims it does it.

I agree with @travisgriggs, priority inheritance should be a default feature of the kernel.

I'm really happy that RIOT is about to get priority inheritance. But let's not forget that until know, everything that runs on RIOT did so without until now. noone has shown a real world application where priority inheritance would have saved the day, but cannot be trivially fixed through other means.

There might be a chicken-and-egg problem: anyone who knows his job and does real-time looks at RIOT, sees "no PI", and moves on, and thus we do not have users that might be happier with priority inheritance enabled. That might be the case, but IMO, having priority inheritance available but optional should solve this.

So now we have this feature, but enabling costs RAM, ROM and performance. The proposal is to enable it by default. So every application will now have to pay that price from now on (e.g., on upgrading to the latest release)? To, me that is unacceptable. It is feature bloat that we have to avoid.

I suggest keeping it optional, adding it to the features list, adding prominent documentation notes, and adding some kind of realtime guidelines where we suggest enabling priority inversion.

Apart from that, let's keep it disabled.

I also think that having this enabled by default with the possibility of disabling will be beneficial for everyone.

Beneficial why? I have not yet seen an argument pro "priority inheritance by default" other than "others do it" and "I think it should be done".

@gdoffe you were using RIOT for robotics in a real-time environment? What's your take on this?

@bergzand
Copy link
Member

@kaspar030 I would like to have this merged without PI enabled by default and then start a discussion in a separate issue with @gdoffe and @astralien3000. I think we all agree that it is better to have PI as an option in RIOT than to stall this PR more than necessary to discuss whether we want to have it enabled by default.

@kaspar030
Copy link
Contributor

I would like to have this merged without PI enabled by default and then start a discussion in a separate issue

totally!

@danpetry
Copy link
Contributor

Sounds like a plan. I've started an issue #9379 to discuss further. Hopefully everyone feels that their view is accurately represented in the summary, let me know if not.

@miri64 miri64 added State: waiting for other PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Oct 5, 2018
@stale
Copy link

stale bot commented Aug 10, 2019

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.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Aug 10, 2019
@haukepetersen haukepetersen added the State: don't stale State: Tell state-bot to ignore this issue label Aug 12, 2019
@stale stale bot removed the State: stale State: The issue / PR has no activity for >185 days label Aug 12, 2019
@jia200x
Copy link
Member

jia200x commented Apr 8, 2020

Let's continue with this!
Besides the rebase, are there any show stoppers?

@OlegHahm
Copy link
Member

OlegHahm commented Mar 9, 2022

Do we still need this after #17093 got merged?

@MrKevinWeiss
Copy link
Contributor

ping

@maribu
Copy link
Member

maribu commented Aug 30, 2022

Since an alternative implementation is merged by now, this is no longer needed

@maribu maribu closed this Aug 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: core Area: RIOT kernel. Handle PRs marked with this with care! State: don't stale State: Tell state-bot to ignore this issue State: waiting for other PR State: The PR requires another PR to be merged first Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.