Bluetooth: controller: Move LLL done handling from ULL to LLL

Move the LLL done event handling from ULL to LLL, this
reduces CPU utilization and reduces overhead between radio
events.

Fixes #21993.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2021-03-28 07:02:57 +05:30 committed by Anas Nashif
parent 5be2149c48
commit 661991405b
3 changed files with 46 additions and 3 deletions

View file

@ -312,6 +312,7 @@ config BT_CTLR_ULL_LOW_PRIO
config BT_CTLR_LOW_LAT
bool "Low latency non-negotiating event preemption"
select BT_CTLR_LOW_LAT_ULL_DONE
default y if SOC_SERIES_NRF51X
help
Use low latency non-negotiating event preemption. This reduces
@ -328,6 +329,12 @@ config BT_CTLR_LOW_LAT_ULL
Low latency ULL implementation that uses tailchaining instead of while
loop to demux rx messages from LLL.
config BT_CTLR_LOW_LAT_ULL_DONE
prompt "Low latency ULL prepare dequeue"
bool
help
Done events be processed and dequeued in ULL context.
config BT_CTLR_CONN_META
prompt "Enable connection meta data extension"
bool

View file

@ -50,17 +50,21 @@ static struct {
lll_abort_cb_t abort_cb;
} curr;
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
struct {
uint8_t volatile lll_count;
uint8_t ull_count;
} done;
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
} event;
/* Entropy device */
static const struct device *dev_entropy;
static int init_reset(void);
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
static inline void done_inc(void);
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int prio,
struct lll_prepare_param *prepare_param,
@ -283,6 +287,14 @@ void lll_disable(void *param)
next->is_aborted = 1;
next->abort_cb(&next->prepare_param,
next->prepare_param.param);
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
/* NOTE: abort_cb called lll_done which modifies
* the prepare pipeline hence re-iterate
* through the prepare pipeline.
*/
idx = UINT8_MAX;
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
}
next = ull_prepare_dequeue_iter(&idx);
@ -331,7 +343,9 @@ int lll_done(void *param)
param = event.curr.param;
event.curr.param = NULL;
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
done_inc();
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
if (param) {
ull = HDR_ULL(((struct lll_hdr *)param)->parent);
@ -349,6 +363,10 @@ int lll_done(void *param)
ull = HDR_ULL(((struct lll_hdr *)param)->parent);
}
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
ull_prepare_dequeue(TICKER_USER_ID_LLL);
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
/* Let ULL know about LLL event done */
evdone = ull_event_done(ull);
LL_ASSERT(evdone);
@ -356,10 +374,12 @@ int lll_done(void *param)
return ret;
}
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
void lll_done_sync(void)
{
event.done.ull_count = event.done.lll_count;
}
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
bool lll_is_done(void *param)
{
@ -582,14 +602,20 @@ static int init_reset(void)
return 0;
}
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
static inline void done_inc(void)
{
event.done.lll_count++;
}
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
static inline bool is_done_sync(void)
{
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
return event.done.lll_count == event.done.ull_count;
#else /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
return true;
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
}
static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
@ -826,6 +852,14 @@ static void preempt(void *param)
iter->is_aborted = 1;
iter->abort_cb(&iter->prepare_param,
iter->prepare_param.param);
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
/* NOTE: abort_cb called lll_done which modifies
* the prepare pipeline hence re-iterate
* through the prepare pipeline.
*/
idx = UINT8_MAX;
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
}
iter = ull_prepare_dequeue_iter(&iter_idx);

View file

@ -197,7 +197,6 @@
/* Define ticker user operations */
#if defined(CONFIG_BT_CTLR_LOW_LAT) && \
(CONFIG_BT_CTLR_LLL_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO)
#define TICKER_USER_LLL_OPS (3 + TICKER_USER_LLL_VENDOR_OPS + 1)
/* NOTE: When ticker job is disabled inside radio events then all advertising,
* scanning, and slave latency cancel ticker operations will be deferred,
* requiring increased ticker thread context operation queue count.
@ -208,13 +207,14 @@
TICKER_USER_THREAD_FLASH_OPS + \
1)
#else /* !CONFIG_BT_CTLR_LOW_LAT */
#define TICKER_USER_LLL_OPS (2 + TICKER_USER_LLL_VENDOR_OPS + 1)
/* NOTE: As ticker job is not disabled inside radio events, no need for extra
* thread operations queue element for flash driver.
*/
#define TICKER_USER_THREAD_OPS (1 + TICKER_USER_THREAD_VENDOR_OPS + 1)
#endif /* !CONFIG_BT_CTLR_LOW_LAT */
#define TICKER_USER_ULL_LOW_OPS (1 + 1)
/* NOTE: When ULL_LOW priority is configured to lower than ULL_HIGH, then extra
* ULL_HIGH operations queue elements are required to buffer the
* requested ticker operations.
@ -222,7 +222,7 @@
#define TICKER_USER_ULL_HIGH_OPS (3 + TICKER_USER_ULL_HIGH_VENDOR_OPS + \
TICKER_USER_ULL_HIGH_FLASH_OPS + 1)
#define TICKER_USER_ULL_LOW_OPS (1 + 1)
#define TICKER_USER_LLL_OPS (3 + TICKER_USER_LLL_VENDOR_OPS + 1)
#define TICKER_USER_OPS (TICKER_USER_LLL_OPS + \
TICKER_USER_ULL_HIGH_OPS + \
@ -2374,11 +2374,13 @@ static inline void rx_demux_event_done(memq_link_t *link,
release = done_release(link, done);
LL_ASSERT(release == done);
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE)
/* dequeue prepare pipeline */
ull_prepare_dequeue(TICKER_USER_ID_ULL_HIGH);
/* LLL done synchronized */
lll_done_sync();
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
/* ull instance will resume, dont decrement ref */
if (!ull_hdr) {