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

conditions required for safe call of kernel operations from interrupts #21341

Closed
pabigot opened this issue Dec 12, 2019 · 2 comments
Closed

conditions required for safe call of kernel operations from interrupts #21341

pabigot opened this issue Dec 12, 2019 · 2 comments
Assignees

Comments

@pabigot
Copy link
Collaborator

pabigot commented Dec 12, 2019

While trying to fully understand what kernel services can be used in what context, in support of #18970 and possibly #21111, I noticed what appears to be an anomaly.

My current assessment from code and documentation is that an operation cannot be invoked from an ISR if (reference thread states):

  • It transitions the current thread to Waiting (per documentation and implementation of e.g. k_sem_take())
  • It transitions the current thread to Ready (per assert in k_yield())
  • It transitions the current thread to Suspended (per assert inz_tick_sleep())

The latter is one that doesn't fit.

k_sleep(t) for a non-zero t will invoke z_ticks_sleep() which asserts if it's called from interrupt context.

k_sleep(K_FOREVER) will instead invoke k_thread_suspend(_current) which is (not dis-) allowed from interrupt context.

Questions:

(A) Is this behavior as intended? (my vote is k_sleep(K_FOREVER) in interrupt context should be disallowed.)

(B) What is the precise set of conditions under which an operation cannot be invoked from an ISR?

(C) Is that set of conditions different from the set under which an operation cannot be invoked from a pre-kernel init function?

@andrewboie
Copy link
Contributor

@pabigot this just seems like an omission, k_sleep() and all its variants should assert if called from interrupt context, it makes no sense to call this API from an ISR.

What is the precise set of conditions under which an operation cannot be invoked from an ISR?

Actions are forbidden in an ISR if they would put the caller to sleep, since we are not in context of any particular thread. Other OSes have the same policy Zephyr is not special here.

Is that set of conditions different from the set under which an operation cannot be invoked from a pre-kernel init function?

Pre-kernel functions have the same restriction about sleeping (no thread context) plus certain data structures may not have been initialized like drivers and kernel objects. I do believe this is documented.

@pabigot
Copy link
Collaborator Author

pabigot commented Dec 12, 2019

@andrewboie Thanks, that's clear and I can make it work in the API terminology. I was getting wrapped around an axle because it seemed that k_sem_give(), which can be invoked from an ISR (I believe) could, when invoked by a preemptible thread, cause its caller to sleep, but that's because it's a reschedule point rather than because the function itself might sleep.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants