Commit af4d9093 authored by Morten Priess's avatar Morten Priess Committed by Chris Friedt
Browse files

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: default avatarMorten Priess <mtpr@oticon.com>
parent 62ad640b
Loading
Loading
Loading
Loading
+3 −0
Changes for subsys/bluetooth/controller/ll_sw/ull.c: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1667,12 +1667,15 @@ int ull_disable(void *lll)
	if (!hdr || !ull_ref_get(hdr)) {
		return 0;
	}
	cpu_dmb(); /* Ensure synchronized data access */

	k_sem_init(&sem, 0, 1);

	hdr->disabled_param = &sem;
	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
	 * decrement the ref count. Hence, handle this race condition by
	 * ensuring that `disabled_cb` has been set while the ref count is still