Bluetooth: Controller: Use reschedule margin as minimum ticks_slot

Use reschedule margin as minimum ticks_slot when ticker with
reschedule expires. This will ensure not too many unreserved
tickers expire in close proximity that can lead of pile up
of CPU processing time and eventually causing timeout
callbacks to be delayed. This mitigate possible LL asserts
due to overhead in start of radio events.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2024-04-12 12:28:24 +02:00 committed by Fabio Baltieri
parent 263357e042
commit 64f41309d1
2 changed files with 36 additions and 8 deletions

View File

@ -68,8 +68,9 @@
HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC)
/* Macro defining the margin for positioning re-scheduled nodes */
#define HAL_TICKER_RESCHEDULE_MARGIN_US 150U
#define HAL_TICKER_RESCHEDULE_MARGIN \
HAL_TICKER_US_TO_TICKS(150)
HAL_TICKER_US_TO_TICKS(HAL_TICKER_RESCHEDULE_MARGIN_US)
/* Remove ticks and return positive remainder value in microseconds */
static inline void hal_ticker_remove_jitter(uint32_t *ticks,

View File

@ -840,6 +840,7 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
while (id_head != TICKER_NULL) {
struct ticker_node *ticker_next = &nodes[id_head];
uint32_t ticker_next_ticks_slot;
/* Accumulate ticks_to_expire for each node */
acc_ticks_to_expire += ticker_next->ticks_to_expire;
@ -847,8 +848,17 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
break;
}
if (TICKER_HAS_SLOT_WINDOW(ticker_next) &&
(ticker_next->ticks_slot == 0U)) {
ticker_next_ticks_slot =
HAL_TICKER_RESCHEDULE_MARGIN;
} else {
ticker_next_ticks_slot =
ticker_next->ticks_slot;
}
/* We only care about nodes with slot reservation */
if (ticker_next->ticks_slot == 0U) {
if (ticker_next_ticks_slot == 0U) {
id_head = ticker_next->next;
continue;
}
@ -977,7 +987,8 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
/* Check if next node is within this reservation slot
* and wins conflict resolution
*/
if (curr_has_ticks_slot_window ||
if ((curr_has_ticks_slot_window &&
next_not_ticks_slot_window) ||
(!lazy_next_periodic_skip &&
(next_is_critical ||
next_force ||
@ -1295,11 +1306,19 @@ void ticker_worker(void *param)
#if !defined(CONFIG_BT_TICKER_LOW_LAT) && \
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC)
uint32_t ticker_ticks_slot;
if (TICKER_HAS_SLOT_WINDOW(ticker) &&
(ticker->ticks_slot == 0U)) {
ticker_ticks_slot = HAL_TICKER_RESCHEDULE_MARGIN;
} else {
ticker_ticks_slot = ticker->ticks_slot;
}
/* Check if node has slot reservation and resolve any collision
* with other ticker nodes
*/
if (((ticker->ticks_slot != 0U) ||
TICKER_HAS_SLOT_WINDOW(ticker)) &&
if ((ticker_ticks_slot != 0U) &&
(slot_reserved ||
(instance->ticks_slot_previous > ticks_expired) ||
ticker_resolve_collision(node, ticker))) {
@ -1431,7 +1450,7 @@ void ticker_worker(void *param)
#if !defined(CONFIG_BT_TICKER_LOW_LAT) && \
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC)
if (ticker->ticks_slot != 0U) {
if (ticker_ticks_slot != 0U) {
/* Any further nodes will be skipped */
slot_reserved = 1U;
}
@ -2061,13 +2080,21 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
instance->ticks_slot_previous = 0U;
}
uint32_t ticker_ticks_slot;
if (TICKER_HAS_SLOT_WINDOW(ticker) && !ticker->ticks_slot) {
ticker_ticks_slot = HAL_TICKER_RESCHEDULE_MARGIN;
} else {
ticker_ticks_slot = ticker->ticks_slot;
}
/* If a reschedule is set pending, we will need to keep
* the slot_previous information
*/
if (ticker->ticks_slot && (state == 2U) && !skip_collision &&
if (ticker_ticks_slot && (state == 2U) && !skip_collision &&
!TICKER_RESCHEDULE_PENDING(ticker)) {
instance->ticker_id_slot_previous = id_expired;
instance->ticks_slot_previous = ticker->ticks_slot;
instance->ticks_slot_previous = ticker_ticks_slot;
}
#endif /* CONFIG_BT_TICKER_SLOT_AGNOSTIC */