From 772a77718ed952150c1702586dae893562030427 Mon Sep 17 00:00:00 2001 From: Morten Priess Date: Wed, 3 Mar 2021 16:13:35 +0100 Subject: [PATCH] Bluetooth: controller: Framework for new feature BT_CTLR_JIT_SCHEDULING This option enables BT_TICKER_SLOT_AGNOSTIC which eliminates priorities and collision resolving in the ticker. Event scheduling states are stored in the lll_hdr, and event priority is passed from LLL implementation, and runtime priority calculated. LLL implementation decides whether to program radio, start preemption timer, and/or queue prepare in the prepare pipeline. Event arbitration is made possible via the common LLL, but not yet implemented in Nordic LLL. Signed-off-by: Morten Priess --- .../bluetooth/controller/Kconfig.ll_sw_split | 9 +++++ subsys/bluetooth/controller/ll_sw/lll.h | 14 +++++++ .../bluetooth/controller/ll_sw/lll_common.c | 40 ++++++++++++++++++- .../controller/ll_sw/nordic/lll/lll.c | 4 ++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 6755cffa1d5..b38eb9498d1 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -570,6 +570,15 @@ config BT_TICKER_SLOT_AGNOSTIC reservations and collision handling, and operates as a simple multi-instance programmable timer. +config BT_CTLR_JIT_SCHEDULING + bool "Just-in-Time Scheduling" + select BT_TICKER_SLOT_AGNOSTIC + help + This option enables the experimental 'Next Generation' scheduling + feature, which eliminates priorities and collision resolving in the + ticker, and instead relies on just-in-time ("lazy") resolution in + the link layer. + config BT_CTLR_USER_EXT prompt "Enable proprietary extensions in Controller" bool diff --git a/subsys/bluetooth/controller/ll_sw/lll.h b/subsys/bluetooth/controller/ll_sw/lll.h index 4920be6ed6b..5e91f9a914f 100644 --- a/subsys/bluetooth/controller/ll_sw/lll.h +++ b/subsys/bluetooth/controller/ll_sw/lll.h @@ -160,12 +160,19 @@ struct ull_hdr { struct lll_hdr { void *parent; +#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + uint8_t score; + uint8_t latency; +#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ }; struct lll_prepare_param { uint32_t ticks_at_expire; uint32_t remainder; uint16_t lazy; +#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + int8_t prio; +#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ uint8_t force; void *param; }; @@ -379,8 +386,15 @@ static inline void lll_hdr_init(void *lll, void *parent) struct lll_hdr *hdr = lll; hdr->parent = parent; + +#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + hdr->score = 0U; + hdr->latency = 0U; +#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ } +void lll_done_score(void *param, uint8_t too_late, uint8_t aborted); + int lll_init(void); int lll_reset(void); void lll_resume(void *param); diff --git a/subsys/bluetooth/controller/ll_sw/lll_common.c b/subsys/bluetooth/controller/ll_sw/lll_common.c index 1d2e83fe864..e92600b9f49 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_common.c +++ b/subsys/bluetooth/controller/ll_sw/lll_common.c @@ -41,7 +41,27 @@ int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, lll_prepare_cb_t prepare_cb, int8_t event_prio, struct lll_prepare_param *prepare_param) { - /* TODO: Calculate priority */ +#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + int prio = event_prio; + struct lll_hdr *hdr = prepare_param->param; + + /* Establish priority based on: + * 1. Event priority passed to function + * 2. Force flag => priority = -127 + * 3. Score (events terminated- and too late) + * 4. Latency (skipped- and programmed latency) + * 5. Critical priority is immutable (-128) + */ + if (prio > -128) { + if (prepare_param->force) { + prio = -127; + } else { + prio = MAX(-127, prio - hdr->score - hdr->latency); + } + } + + prepare_param->prio = prio; +#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ return lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb, prepare_param, 0, 0); @@ -58,3 +78,21 @@ void lll_resume(void *param) next->is_resume, 1); LL_ASSERT(!ret || ret == -EINPROGRESS); } + +#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) +void lll_done_score(void *param, uint8_t too_late, uint8_t aborted) +{ + struct lll_hdr *hdr = param; + + if (!hdr) { + return; + } + + if (!too_late && !aborted) { + hdr->score = 0; + hdr->latency = 0; + } else { + hdr->score++; + } +} +#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 6a2b2e83fd1..716995d8288 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -344,6 +344,10 @@ int lll_done(void *param) ull_prepare_dequeue(TICKER_USER_ID_LLL); #endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */ +#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) + lll_done_score(param, 0, 0); /* TODO */ +#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ + /* Let ULL know about LLL event done */ evdone = ull_event_done(ull); LL_ASSERT(evdone);