From 1b5b62962431060559bb5c8516b5fb340c67875f Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sat, 17 Oct 2020 15:18:05 +0700 Subject: scheduler: remove pending Tx prims on lchan deactivation Sometimes the following messages appear in the logging output: TCH/F: Prim has wrong chan_nr=0xc5 link_id=00, expecting chan_nr=0x0d link_id=00 TCH/F: Prim has wrong chan_nr=0xc2 link_id=00, expecting chan_nr=0x0a link_id=00 when a dynamic timeslot is switched from PDCH to TCH/F (or to TCH/H). This means that the transmit queue of a timeslot still contains PDCH frames, that were not properly cleaned on PDCH deactivation. Let's finally do this in trx_sched_set_lchan(). Change-Id: Ic6560c660c658f36b84e7efa2f1d93e3a870962b Related: SYS#5108, OS#4804 --- src/common/scheduler.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 5bf1c5bc..b61330d2 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -968,6 +968,37 @@ int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn, return 0; } +/* Remove all matching (by chan_nr & link_id) primitives from the given queue */ +static void trx_sched_queue_filter(struct llist_head *q, uint8_t chan_nr, uint8_t link_id) +{ + struct msgb *msg, *_msg; + + llist_for_each_entry_safe(msg, _msg, q, list) { + struct osmo_phsap_prim *l1sap = msgb_l1sap_prim(msg); + switch (l1sap->oph.primitive) { + case PRIM_PH_DATA: + if (l1sap->u.data.chan_nr != chan_nr) + continue; + if (l1sap->u.data.link_id != link_id) + continue; + break; + case PRIM_TCH: + if (l1sap->u.tch.chan_nr != chan_nr) + continue; + if (link_id != 0x00) + continue; + break; + default: + /* Shall not happen */ + OSMO_ASSERT(0); + } + + /* Unlink and free() */ + llist_del(&msg->list); + talloc_free(msg); + } +} + /* setting all logical channels given attributes to active/inactive */ int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_id, bool active) { @@ -1011,6 +1042,9 @@ int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_i OSMO_ASSERT(chan_state->lchan != NULL); } else { chan_state->ho_rach_detect = 0; + + /* Remove pending Tx prims belonging to this lchan */ + trx_sched_queue_filter(&l1ts->dl_prims, chan_nr, link_id); } chan_state->active = active; -- cgit v1.2.3