Skip to content

Commit 87b39c5

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: Controller: Fix repeated skip in ticker resolve collision
Enforce next_is_older only when current has equal force as with the next ticker. Added Kconfig to disable priority feature in ticker that is currently not used by Zephyr Bluetooth Low Energy Controller. The priority feature if enabled then a custom ULL is needed by vendors to avoid repeated skipping of overlapping events as next_has_priority check uses lazy value that would be always lazy_next > lazy_current as currently skipped event becomes the next event with lazy value incremented by 1. Regression in commit 3a9173a ("bluetooth: controller: Revised ticker for improved conflict resolution") due to Zephyr Controller does not implement any vendor specific priority logic. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 24f989c commit 87b39c5

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

subsys/bluetooth/controller/Kconfig.ll_sw_split

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,21 @@ config BT_TICKER_EXT_SLOT_WINDOW_YIELD
808808
This options forces tickers with slot window extensions to yield to
809809
normal tickers and be placed at the end of their slot window.
810810

811+
config BT_TICKER_PRIORITY_SET
812+
bool "Tickers with priority based collision resolution"
813+
depends on BT_TICKER_EXT
814+
help
815+
This option provide tickers with persistent priority value that will
816+
be used in resolving collisions.
817+
818+
The priority feature if enabled then a custom ULL is needed by vendors
819+
to avoid repeated skipping of overlapping events as next_has_priority
820+
check uses lazy value that would be always lazy_next > lazy_current as
821+
currently skipped event becomes the next event with lazy value
822+
incremented by 1. This repeated skip happens when all the time
823+
between the event intervals are occupied continuously by overlapping
824+
tickers.
825+
811826
config BT_TICKER_SLOT_AGNOSTIC
812827
bool "Slot agnostic ticker mode"
813828
help

subsys/bluetooth/controller/ticker/ticker.c

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ struct ticker_node {
8181
uint8_t must_expire; /* Node must expire, even if it
8282
* collides with other nodes
8383
*/
84+
#if defined(CONFIG_BT_TICKER_PRIORITY_SET)
8485
int8_t priority; /* Ticker node priority. 0 is
8586
* default. Lower value is higher
8687
* priority
8788
*/
89+
#endif /* CONFIG_BT_TICKER_PRIORITY_SET */
8890
#endif /* !CONFIG_BT_TICKER_LOW_LAT &&
8991
* !CONFIG_BT_TICKER_SLOT_AGNOSTIC
9092
*/
@@ -745,8 +747,15 @@ static uint32_t ticker_dequeue(struct ticker_instance *instance, uint8_t id)
745747
static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
746748
struct ticker_node *ticker)
747749
{
750+
#if defined(CONFIG_BT_TICKER_PRIORITY_SET)
748751
if ((ticker->priority != TICKER_PRIORITY_CRITICAL) &&
749752
(ticker->next != TICKER_NULL)) {
753+
754+
#else /* !CONFIG_BT_TICKER_PRIORITY_SET */
755+
if (ticker->next != TICKER_NULL) {
756+
757+
#endif /* !CONFIG_BT_TICKER_PRIORITY_SET */
758+
750759
uint16_t lazy_current = ticker->lazy_current;
751760

752761
/* Check if this ticker node will starve next node which has
@@ -802,28 +811,43 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
802811
(ticker->ticks_periodic != 0U) &&
803812
(next_age > current_age);
804813

814+
/* Is the current and next node equal in force? */
815+
uint8_t equal_force =
816+
(ticker->force == ticker_next->force);
805817
/* Is force requested for next node (e.g. update) -
806818
* more so than for current node?
807819
*/
808-
uint8_t next_force = (ticker_next->force > ticker->force);
820+
uint8_t next_force =
821+
(ticker_next->force > ticker->force);
809822

823+
#if defined(CONFIG_BT_TICKER_PRIORITY_SET)
810824
/* Does next node have critical priority and should
811825
* always be scheduled?
812826
*/
813-
uint8_t next_is_critical = ticker_next->priority ==
814-
TICKER_PRIORITY_CRITICAL;
827+
uint8_t next_is_critical =
828+
(ticker_next->priority ==
829+
TICKER_PRIORITY_CRITICAL);
815830

816831
/* Is the current and next node equal in priority? */
817832
uint8_t equal_priority =
818833
(ticker->priority == ticker_next->priority);
819834

835+
#else /* !CONFIG_BT_TICKER_PRIORITY_SET */
836+
uint8_t next_is_critical = 0U;
837+
uint8_t equal_priority = 1U;
838+
uint8_t next_has_priority = 0U;
839+
840+
#endif /* !CONFIG_BT_TICKER_PRIORITY_SET */
841+
820842
#if defined(CONFIG_BT_TICKER_EXT_SLOT_WINDOW_YIELD)
843+
#if defined(CONFIG_BT_TICKER_PRIORITY_SET)
821844
/* Does next node have higher priority? */
822845
uint8_t next_has_priority =
823846
(!ticker_next->ext_data ||
824847
!ticker_next->ext_data->ticks_slot_window) &&
825848
((lazy_next - ticker_next->priority) >
826849
(lazy_current - ticker->priority));
850+
#endif /* CONFIG_BT_TICKER_PRIORITY_SET */
827851

828852
/* Can the current ticker with ticks_slot_window be
829853
* scheduled after the colliding ticker?
@@ -848,10 +872,12 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
848872
ticker_next->ticks_slot) <
849873
ticker->ticks_slot));
850874
#else /* !CONFIG_BT_TICKER_EXT_SLOT_WINDOW_YIELD */
875+
#if defined(CONFIG_BT_TICKER_PRIORITY_SET)
851876
/* Does next node have higher priority? */
852877
uint8_t next_has_priority =
853878
(lazy_next - ticker_next->priority) >
854879
(lazy_current - ticker->priority);
880+
#endif /* CONFIG_BT_TICKER_PRIORITY_SET */
855881

856882
uint8_t curr_has_ticks_slot_window = 0U;
857883
uint8_t next_not_ticks_slot_window = 1U;
@@ -862,10 +888,10 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes,
862888
*/
863889
if (curr_has_ticks_slot_window ||
864890
(!lazy_next_periodic_skip &&
865-
(next_force ||
866-
next_is_critical ||
891+
(next_is_critical ||
892+
next_force ||
867893
(next_has_priority && !current_is_older) ||
868-
(equal_priority && next_is_older &&
894+
(equal_priority && equal_force && next_is_older &&
869895
next_not_ticks_slot_window)))) {
870896
/* This node must be skipped - check window */
871897
return 1U;
@@ -2308,12 +2334,15 @@ static inline void ticker_job_op_inquire(struct ticker_instance *instance,
23082334
NULL);
23092335
#endif /* !CONFIG_BT_TICKER_LAZY_GET */
23102336
__fallthrough;
2337+
23112338
case TICKER_USER_OP_TYPE_IDLE_GET:
23122339
uop->status = TICKER_STATUS_SUCCESS;
23132340
fp_op_func = uop->fp_op_func;
23142341
break;
2342+
23152343
#if !defined(CONFIG_BT_TICKER_LOW_LAT) && \
2316-
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC)
2344+
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) && \
2345+
defined(CONFIG_BT_TICKER_PRIORITY_SET)
23172346
case TICKER_USER_OP_TYPE_PRIORITY_SET:
23182347
if (uop->id < instance->count_node) {
23192348
struct ticker_node *node = instance->nodes;
@@ -2328,7 +2357,9 @@ static inline void ticker_job_op_inquire(struct ticker_instance *instance,
23282357
break;
23292358
#endif /* !CONFIG_BT_TICKER_LOW_LAT &&
23302359
* !CONFIG_BT_TICKER_SLOT_AGNOSTIC
2360+
* CONFIG_BT_TICKER_PRIORITY_SET
23312361
*/
2362+
23322363
default:
23332364
/* do nothing for other ops */
23342365
break;
@@ -2635,12 +2666,14 @@ uint32_t ticker_init(uint8_t instance_index, uint8_t count_node, void *node,
26352666
instance->nodes = node;
26362667

26372668
#if !defined(CONFIG_BT_TICKER_LOW_LAT) && \
2638-
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC)
2669+
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) && \
2670+
defined(CONFIG_BT_TICKER_PRIORITY_SET)
26392671
while (count_node--) {
26402672
instance->nodes[count_node].priority = 0;
26412673
}
26422674
#endif /* !CONFIG_BT_TICKER_LOW_LAT &&
26432675
* !CONFIG_BT_TICKER_SLOT_AGNOSTIC
2676+
* CONFIG_BT_TICKER_PRIORITY_SET
26442677
*/
26452678

26462679
instance->count_user = count_user;
@@ -3223,7 +3256,8 @@ uint32_t ticker_job_idle_get(uint8_t instance_index, uint8_t user_id,
32233256
}
32243257

32253258
#if !defined(CONFIG_BT_TICKER_LOW_LAT) && \
3226-
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC)
3259+
!defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) && \
3260+
defined(CONFIG_BT_TICKER_PRIORITY_SET)
32273261
/**
32283262
* @brief Set ticker node priority
32293263
*
@@ -3281,7 +3315,8 @@ uint32_t ticker_priority_set(uint8_t instance_index, uint8_t user_id, uint8_t ti
32813315
return user_op->status;
32823316
}
32833317
#endif /* !CONFIG_BT_TICKER_LOW_LAT &&
3284-
* !CONFIG_BT_TICKER_SLOT_AGNOSTIC
3318+
* !CONFIG_BT_TICKER_SLOT_AGNOSTIC &&
3319+
* CONFIG_BT_TICKER_PRIORITY_SET
32853320
*/
32863321

32873322
/**

0 commit comments

Comments
 (0)