zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.5k stars 6.43k forks source link

Document which functions add implicit barriers #10884

Open pdunaj opened 5 years ago

pdunaj commented 5 years ago

To make sure that code is not reordered around functions that are critical for correct behavior of multi-threading, such functions should add barriers (compiler one or in case of MP systems proper hw instruction).

This is mostly important for locks of all kinds. (E.g. Linux kernel documentation states that locks add barriers). This is not however the only case, consider following code:

while (checkme) {
   k_sleep(FEW_MS);
}

In normal case a function call to k_sleep will ensure that value of checkme is reloaded (as this is a call to external linkage function). The problem will appear when lto is enabled. In this case k_sleep code can be imported and reload of checkme optimized out. Zephyr should ensure that (if not all) then some of the kernel functions will be implicit barriers. This should also be documented.

carlescufi commented 5 years ago

Note that we do have this already in irq_lock/unlock at least for Arm

ioannisg commented 5 years ago

Title is a little bit broad, IMO. Which "context-switch"-related functions require instruction/memory barriers and why? Are you referring to internal (arch) functions that implement the context switch? Pls, elaborate a bit more :)

pdunaj commented 5 years ago

@carlescufi , I just checked and you are right. Maybe we should add information in the documentation about functions with implicit barrier. I read comment in k_sleep code explaining the volatile used there and I think such item is needed.

Let me rephrase it... As long as it is not clearly documented that irq_lock has a barrier (and so it is expected to appear in all architectures), user will be unsure if the barrier is needed or not.

pizi-nordic commented 5 years ago

@pdunaj is correct that not all cases are covered. For example on SMP, the irq_lock() is a call to global _smp_global_lock() and there is no compiler barrier on the call level. POSIX also might have some trouble caused by ordering.

pdunaj commented 5 years ago

@ioannisg , I have create the ticket as I could find no information in the documentation which functions add barriers and which don't + I have seen comment about volatile in k_sleep that could suggest that kernel does not guarantee irq_lock to have barrier.

I have checked the code in kernel and functions I checked either are using compiler_barrier or are calling irq_lock. So it should be fine as long as irq_lock is barrier itself.

I think that I gave a wrong title to the issue. It should be more about confirming which functions are guaranteed to add a barrier. I will fix it.