Bluetooth: controller: split: Fix ull_disable hang
Under race conditions it is possible that there is no call to k_sem_give to the waiting k_sem_take in the ull_disable function. ull_disable function checks for reference count before using a mayfly to schedule lll_disable, which in turn would close requested currently active role event leading to done event being propogated to ULL. Done event would then call the set disabled_cb callback when the reference count is zero, giving the semaphore to the waiting k_sem_give in the ull_disable. Under race conditions if the reference count reached zero after the reference count check and before the disabled_cb was assigned in the ull_disable function, then there are chances that a k_sem_give is not called while ull_disable proceeds to waiting using k_sem_take. Fixes #21586. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
3d5c911612
commit
b5c63c69ca
1 changed files with 6 additions and 1 deletions
|
@ -1035,14 +1035,19 @@ int ull_disable(void *lll)
|
|||
u32_t ret;
|
||||
|
||||
hdr = HDR_ULL(((struct lll_hdr *)lll)->parent);
|
||||
if (!hdr || !hdr->ref) {
|
||||
if (!hdr) {
|
||||
return ULL_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
k_sem_init(&sem, 0, 1);
|
||||
|
||||
hdr->disabled_param = &sem;
|
||||
hdr->disabled_cb = disabled_cb;
|
||||
|
||||
if (!hdr->ref) {
|
||||
return ULL_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
mfy.param = lll;
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_LLL, 0,
|
||||
&mfy);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue