Skip to content

arch: arm: restrict IRQ lock to minimum during pendSV exception #15735

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

Merged

Conversation

ioannisg
Copy link
Member

When performing thread context-switch it is not necessary to
have IRQs locked while saving the current thread's callee-saved
(and possibly floating point) registers. We only need to lock
the interrupts when accessing the thread ready queue cache.

Signed-off-by: Ioannis Glaropoulos [email protected]

When performing thread context-switch it is not necessary to
have IRQs locked while saving the current thread's callee-saved
(and possibly floating point) registers. We only need to lock
the interrupts when accessing the thread ready queue cache.

Signed-off-by: Ioannis Glaropoulos <[email protected]>
@ioannisg
Copy link
Member Author

This patch is an optimization; reduces the time we lock the IRQs during context switch.
The principle is simple - we only need to protect during accessing the thread ready queue, not when we are saving the context of the current thread.

The patch is based on the assumption that _current is only changed by this function, a few instructions later, when the new thread is switched in. @andyross @pizi-nordic could you confirm this?

@andrewboie
Copy link
Contributor

can you illustrate what happens if, during this window where we have partially saved the register state, we get an interrupt which causes the system to decide to schedule some other thread?

@andyross
Copy link
Collaborator

So... yes, the _current pointer only gets assigned in the arch-defined z_swap() implementation (or for USE_SWITCH architectures, the kernel-provided portable one). You're safe as far as that goes.

But remember that PendSV is not atomic with respect to the original call to z_swap(). The thread to which you are swapping is not necessarily the one the kernel thread "thought" it was switching to when it called z_swap() in the first place. If , as I understand the commit message, all the unlocked code here is doing is writing to stack memory (and the stack pointer is always consistent!) then this should be OK. But if you're inspecting or writing to other memory it's likely to have holes.

@ioannisg
Copy link
Member Author

@andyross thanks very much for your feedback.

@andrewboie sure, I can briefly comment on this:
The ARM call procedure standard ensures that the register content remains the same after any interrupt that preempts a lower-priority interrupt - the context-switch (pendSV) in our case:

  • caller-saved registers are stacked and restored on current MSP by the exception entry/return
  • callee-saved registers are always restored on sub-routine return

A preempting ISR will, therefore, allow the context saving to safely resume when returning to the pendSV.

Also, for ARM an interrupt cannot be, normally, nested in its own. Therefore, the pendSV cannot be interrupted by another pendSV playing with context saving!

All this patch is doing is to un-protect the context saving of the current thread; as I argued above, this seems not needed, as the _current pointer is not changed by any other Kernel/ARCH code. It is only touched later in the swap routine.

If a preempting interrupt decides to schedule some other thread, it will modify the ready queue cache, but that is fine, until the very last moment we will need to read this! And that part of the swap-routine is still protected inside interrupts lock-unlock.

@ioannisg
Copy link
Member Author

@pizi-nordic pls, have a quick look, as well

@ioannisg ioannisg added the Enhancement Changes/Updates/Additions to existing features label Apr 30, 2019
@ioannisg ioannisg added this to the v2.0.0 milestone Apr 30, 2019
@nashif nashif merged commit 02122bc into zephyrproject-rtos:master Apr 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ARM ARM (32-bit) Architecture area: optimization Enhancement Changes/Updates/Additions to existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants