Bluetooth: Controller: fix mayfly unwanted re-init every bt_enable call
Mayfly by design uses a memq for storage of its jobs. The memq requires head and tail to track the content. It is considered empty is head equals tail. When memq instance is initialized then there is a new link instance stored in head and tail, nevertheless the memq is still empty. When new job is enqueued to a memq, the inilial link is used to store the job. New link, provided by enqueue call, is stored in the tail for future enqueue. When enqueued job was served and is dequeued, the link it was assigned to is returned and stored in the job object. That link will be used in future for call to enqueue. Now lets consider a situation when we are just after initalization. Some default initial link is in empty memq. We enqueue and dequeue a job. After dequeue, the job object stores the initial link object. The one that was put into the memq during initialization. Next Bluetooth stack is disabled and enabled again. The job is enqueued again, but it still stores the initial link address. After enqueue the memq head points to initial link object, that stores new job. Tail points to link deliveded by enqueue call, that is also the initial link object. The memq is considered to be empty, nevertheless there was a successful enqueue operation. The issue is casued by lack of re-initialization of a job object on init. In most cases these objects are static members of some functions, hence there is no re-initialization after bt_disable and bt_enable calls. The problem is fixed by re-initialization of mayfly only once on bt_enable() call. Then it doesn't matter what links are stored in dequeued objects and there is no need to re-initialized mayfly job objects. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
9cd94277bf
commit
e84cabf0d4
|
@ -531,6 +531,7 @@ static void ull_done(void *param);
|
|||
|
||||
int ll_init(struct k_sem *sem_rx)
|
||||
{
|
||||
static bool mayfly_initialized;
|
||||
int err;
|
||||
|
||||
/* Store the semaphore to be used to wakeup Thread context */
|
||||
|
@ -540,8 +541,24 @@ int ll_init(struct k_sem *sem_rx)
|
|||
/* TODO: Bind and use counter driver? */
|
||||
cntr_init();
|
||||
|
||||
/* Initialize Mayfly */
|
||||
mayfly_init();
|
||||
/* Initialize mayfly. It may be done only once due to mayfly design.
|
||||
*
|
||||
* On init mayfly memq head and tail is assigned with a link instance
|
||||
* that is used during enqueue operation. New link provided by enqueue
|
||||
* is added as a tail and will be used in future enqueue. While dequeue,
|
||||
* the link that was used for storage of the job is relesed and stored
|
||||
* in a job it was related to. The job may store initial link. If mayfly
|
||||
* is re-initialized but job objects were not re-initialized there is a
|
||||
* risk that enqueued job will point to the same link as it is in a memq
|
||||
* just after re-initialization. After enqueue operation with that link,
|
||||
* head and tail still points to the same link object, so memq is
|
||||
* considered as empty.
|
||||
*/
|
||||
if (!mayfly_initialized) {
|
||||
mayfly_init();
|
||||
mayfly_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize Ticker */
|
||||
ticker_users[MAYFLY_CALL_ID_0][0] = TICKER_USER_LLL_OPS;
|
||||
|
|
|
@ -192,7 +192,6 @@ void mayfly_run(uint8_t callee_id)
|
|||
(void **)&m);
|
||||
while (link) {
|
||||
uint8_t state;
|
||||
|
||||
#if defined(MAYFLY_UT)
|
||||
_state = 0U;
|
||||
#endif /* MAYFLY_UT */
|
||||
|
|
Loading…
Reference in a new issue