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:
Piotr Pryga 2022-07-11 15:05:52 +02:00 committed by Carles Cufí
parent 9cd94277bf
commit e84cabf0d4
2 changed files with 19 additions and 3 deletions

View file

@ -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;

View file

@ -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 */