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;
|
u32_t ret;
|
||||||
|
|
||||||
hdr = HDR_ULL(((struct lll_hdr *)lll)->parent);
|
hdr = HDR_ULL(((struct lll_hdr *)lll)->parent);
|
||||||
if (!hdr || !hdr->ref) {
|
if (!hdr) {
|
||||||
return ULL_STATUS_SUCCESS;
|
return ULL_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
if (!hdr->ref) {
|
||||||
|
return ULL_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
mfy.param = lll;
|
mfy.param = lll;
|
||||||
ret = mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_LLL, 0,
|
ret = mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_LLL, 0,
|
||||||
&mfy);
|
&mfy);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue