fixeria has uploaded this change for review.

View Change

osmo-bts-trx: fix spurious clock skew shutdown after self-compensation

When the BTS runs ahead of the transceiver (elapsed_fn < 0),
trx_sched_clock() reschedules the timerfd to deliberately delay the
next FN. osmo_timerfd_schedule() resets the timerfd and discards any
accumulated expirations, but last_fn_timer.tv was left pointing at
the previous callback. The next trx_fn_timer_cb() then measures
elapsed_us all the way back to that previous callback - spanning the
deliberate delay (or any OS stall that preceded us) - and falsely
trips the "PC clock skew too high" check, shutting the BTS down
for no good reason.

Advance last_fn_timer.tv to the projected firing time of the
rescheduled timer so that the next callback measures roughly
one FN interval, as expected.

Change-Id: Icdb7db8abe70258ae008d9514b6608bd74bb2881
AI-Assisted: yes (Claude)
Related: OS#6794
---
M src/osmo-bts-trx/scheduler_trx.c
1 file changed, 10 insertions(+), 3 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/55/42855/1
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index 105ad38..a12ac3f 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -603,13 +603,20 @@
/* too many frames have been processed already */
if (elapsed_fn < 0) {
struct timespec first = interval;
- /* set clock to the time or last FN should have been
- * transmitted. */
+ /* set clock to the time our next FN has to be transmitted */
first.tv_nsec += (0 - elapsed_fn) * GSM_TDMA_FN_DURATION_nS;
normalize_timespec(&first);
LOGP(DL1C, LOGL_NOTICE, "We were %d FN faster than TRX, compensating\n", -elapsed_fn);
- /* set time to the time our next FN has to be transmitted */
osmo_timerfd_schedule(&tcs->fn_timer_ofd, &first, &interval);
+ /* Advance last_fn_timer.tv to the projected firing time of the rescheduled
+ * timer (shifted back one interval). osmo_timerfd_schedule() resets the
+ * timerfd, discarding any accumulated expirations, so without this update
+ * trx_fn_timer_cb() would measure elapsed_us all the way back to the previous
+ * callback — spanning the deliberate delay or any OS stall that preceded us —
+ * and falsely trip the clock skew threshold. */
+ tcs->last_fn_timer.tv = tv_now;
+ tcs->last_fn_timer.tv.tv_nsec += (0 - elapsed_fn) * GSM_TDMA_FN_DURATION_nS;
+ normalize_timespec(&tcs->last_fn_timer.tv);
return 0;
}


To view, visit change 42855. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Icdb7db8abe70258ae008d9514b6608bd74bb2881
Gerrit-Change-Number: 42855
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>