Bluetooth: controller: Prevent invalid compiler code reordering
In ull_disable, it is imperative that the callback is set up before a second reference counter check, otherwise it may happen that an LLL done event has already passed when the disable callback and semaphore is assigned. This causes the HCI thread to wait until timeout and assert after ull_ticker_stop_with_mark. For certain compilers, due to compiler optimizations, it can be seen from the assembler code that the callback is assigned after the second reference counter check. By adding memory barriers, the code correctly reorders code to the expected sequence. Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
parent
d397aae027
commit
7f82b6a219
1 changed files with 3 additions and 0 deletions
|
@ -1953,12 +1953,15 @@ int ull_disable(void *lll)
|
||||||
if (!ull_ref_get(hdr)) {
|
if (!ull_ref_get(hdr)) {
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
|
cpu_dmb(); /* Ensure synchronized data access */
|
||||||
|
|
||||||
k_sem_init(&sem, 0, 1);
|
k_sem_init(&sem, 0, 1);
|
||||||
|
|
||||||
hdr->disabled_param = &sem;
|
hdr->disabled_param = &sem;
|
||||||
hdr->disabled_cb = disabled_cb;
|
hdr->disabled_cb = disabled_cb;
|
||||||
|
|
||||||
|
cpu_dmb(); /* Ensure synchronized data access */
|
||||||
|
|
||||||
/* ULL_HIGH can run after we have call `ull_ref_get` and it can
|
/* ULL_HIGH can run after we have call `ull_ref_get` and it can
|
||||||
* decrement the ref count. Hence, handle this race condition by
|
* decrement the ref count. Hence, handle this race condition by
|
||||||
* ensuring that `disabled_cb` has been set while the ref count is still
|
* ensuring that `disabled_cb` has been set while the ref count is still
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue