Skip to content

Potentially blocking call within critical section #2004

Open
@gmarull

Description

@gmarull

In the following controller code:

void
ble_ll_rfmgmt_release(void)
{
struct ble_ll_rfmgmt_data *rfmgmt = &g_ble_ll_rfmgmt_data;
os_sr_t sr;
OS_ENTER_CRITICAL(sr);
ble_ll_event_remove(&rfmgmt->release_ev);
if (g_ble_ll_rfmgmt_data.state != RFMGMT_STATE_OFF) {
ble_ll_event_add(&rfmgmt->release_ev);
}
OS_EXIT_CRITICAL(sr);
}

ble_ll_event_add is called while inside a critical section. This calls:

void
ble_ll_event_add(struct ble_npl_event *ev)
{
ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev);
}

In case of FreeRTOS,

static inline void
ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
{
npl_freertos_eventq_put(evq, ev);
}

void
npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
{
BaseType_t woken;
BaseType_t ret;
if (ev->queued) {
return;
}
ev->queued = true;
if (in_isr()) {
ret = xQueueSendToBackFromISR(evq->q, &ev, &woken);
portYIELD_FROM_ISR(woken);
} else {
ret = xQueueSendToBack(evq->q, &ev, portMAX_DELAY);
}
assert(ret == pdPASS);
}

As you can see above, xQueueSendToBack is called with portMAX_DELAY. I guess at the very least, we should add a zero delay if we're within a critical section. Also, see https://forums.freertos.org/t/critical-sections-freertos-api-calls/17352.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions