<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-trx/+/19205">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Introduce rate counters to detect issues in received Dl bursts from TRXD<br><br>This ones together with rate counters already available in lower layers<br>allows to understand better the source of the problem with stalled tx<br>bursts.<br><br>Change-Id: Ia34f7e7d780ad1e12f24638a07f05fe91f2afea5<br>---<br>M CommonLibs/osmo_signal.h<br>M CommonLibs/trx_rate_ctr.cpp<br>M CommonLibs/trx_rate_ctr.h<br>M Transceiver52M/Transceiver.cpp<br>M Transceiver52M/Transceiver.h<br>5 files changed, 68 insertions(+), 9 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/05/19205/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CommonLibs/osmo_signal.h b/CommonLibs/osmo_signal.h</span><br><span>index de17b1d..5cd90c6 100644</span><br><span>--- a/CommonLibs/osmo_signal.h</span><br><span>+++ b/CommonLibs/osmo_signal.h</span><br><span>@@ -61,4 +61,7 @@</span><br><span> struct trx_counters {</span><br><span>    size_t chan;</span><br><span>         unsigned int tx_stale_bursts; /* Amount of Tx bursts dropped to to arriving too late from TRXD */</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int tx_trxd_fn_repeated;</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int tx_trxd_fn_outoforder;</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int tx_trxd_fn_skipped;</span><br><span> };</span><br><span>diff --git a/CommonLibs/trx_rate_ctr.cpp b/CommonLibs/trx_rate_ctr.cpp</span><br><span>index 76aff7d..c74602a 100644</span><br><span>--- a/CommonLibs/trx_rate_ctr.cpp</span><br><span>+++ b/CommonLibs/trx_rate_ctr.cpp</span><br><span>@@ -103,6 +103,9 @@</span><br><span>        { TRX_CTR_DEV_TX_DROP_EV,       "tx_drop_events" },</span><br><span>        { TRX_CTR_DEV_TX_DROP_SMPL,     "tx_drop_samples" },</span><br><span>       { TRX_CTR_TRX_TX_STALE_BURSTS,  "tx_stale_bursts" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { TRX_CTR_TRX_TRXD_FN_REPEATED, "tx_trxd_fn_repeated" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { TRX_CTR_TRX_TRXD_FN_OUTOFORDER, "tx_trxd_fn_outoforder" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { TRX_CTR_TRX_TRXD_FN_SKIPPED,  "tx_trxd_fn_skipped" },</span><br><span>    { 0, NULL }</span><br><span> };</span><br><span> </span><br><span>@@ -114,6 +117,9 @@</span><br><span>  [TRX_CTR_DEV_TX_DROP_EV]                = { "device:tx_drop_events",  "Number of times Tx samples were dropped by HW" },</span><br><span>         [TRX_CTR_DEV_TX_DROP_SMPL]              = { "device:tx_drop_samples", "Number of Tx samples dropped by HW" },</span><br><span>    [TRX_CTR_TRX_TX_STALE_BURSTS]           = { "trx:tx_stale_bursts",    "Number of Tx burts dropped by TRX due to arriving too late" },</span><br><span style="color: hsl(120, 100%, 40%);">+     [TRX_CTR_TRX_TRXD_FN_REPEATED]          = { "trx:tx_trxd_fn_repeated",        "Number of Tx burts received from TRXD with repeated FN" },</span><br><span style="color: hsl(120, 100%, 40%);">+ [TRX_CTR_TRX_TRXD_FN_OUTOFORDER]        = { "trx:tx_trxd_fn_outoforder","Number of Tx burts received from TRXD with a past FN" },</span><br><span style="color: hsl(120, 100%, 40%);">+ [TRX_CTR_TRX_TRXD_FN_SKIPPED]           = { "trx:tx_trxd_fn_skipped", "Number of Tx burts potentially skipped due to FN jumps" },</span><br><span> };</span><br><span> </span><br><span> static const struct rate_ctr_group_desc trx_chan_ctr_group_desc = {</span><br><span>@@ -166,6 +172,12 @@</span><br><span>                LOGCHAN(chan, DMAIN, INFO) << "rate_ctr update";</span><br><span>             ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TRX_TX_STALE_BURSTS];</span><br><span>             rate_ctr_add(ctr, trx_ctrs_pending[chan].tx_stale_bursts - ctr->current);</span><br><span style="color: hsl(120, 100%, 40%);">+          ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TRX_TRXD_FN_REPEATED];</span><br><span style="color: hsl(120, 100%, 40%);">+             rate_ctr_add(ctr, trx_ctrs_pending[chan].tx_trxd_fn_repeated - ctr->current);</span><br><span style="color: hsl(120, 100%, 40%);">+              ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TRX_TRXD_FN_OUTOFORDER];</span><br><span style="color: hsl(120, 100%, 40%);">+           rate_ctr_add(ctr, trx_ctrs_pending[chan].tx_trxd_fn_outoforder - ctr->current);</span><br><span style="color: hsl(120, 100%, 40%);">+            ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TRX_TRXD_FN_SKIPPED];</span><br><span style="color: hsl(120, 100%, 40%);">+              rate_ctr_add(ctr, trx_ctrs_pending[chan].tx_trxd_fn_skipped - ctr->current);</span><br><span>              /* Mark as done */</span><br><span>           trx_ctrs_pending[chan].chan = PENDING_CHAN_NONE;</span><br><span>     }</span><br><span>diff --git a/CommonLibs/trx_rate_ctr.h b/CommonLibs/trx_rate_ctr.h</span><br><span>index 588ac2f..cef3c21 100644</span><br><span>--- a/CommonLibs/trx_rate_ctr.h</span><br><span>+++ b/CommonLibs/trx_rate_ctr.h</span><br><span>@@ -11,6 +11,9 @@</span><br><span>       TRX_CTR_DEV_TX_DROP_EV,</span><br><span>      TRX_CTR_DEV_TX_DROP_SMPL,</span><br><span>    TRX_CTR_TRX_TX_STALE_BURSTS,</span><br><span style="color: hsl(120, 100%, 40%);">+  TRX_CTR_TRX_TRXD_FN_REPEATED,</span><br><span style="color: hsl(120, 100%, 40%);">+ TRX_CTR_TRX_TRXD_FN_OUTOFORDER,</span><br><span style="color: hsl(120, 100%, 40%);">+       TRX_CTR_TRX_TRXD_FN_SKIPPED,</span><br><span> };</span><br><span> </span><br><span> struct ctr_threshold {</span><br><span>diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp</span><br><span>index 2ae5eda..01714db 100644</span><br><span>--- a/Transceiver52M/Transceiver.cpp</span><br><span>+++ b/Transceiver52M/Transceiver.cpp</span><br><span>@@ -52,6 +52,14 @@</span><br><span> /* Number of running values use in noise average */</span><br><span> #define NOISE_CNT                  20</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void dispatch_trx_rate_ctr_change(TransceiverState *state, unsigned int chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+        thread_enable_cancel(false);</span><br><span style="color: hsl(120, 100%, 40%);">+        state->ctrs.chan = chan;</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_signal_dispatch(SS_DEVICE, S_TRX_COUNTER_CHANGE, &state->ctrs);</span><br><span style="color: hsl(120, 100%, 40%);">+        thread_enable_cancel(true);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> TransceiverState::TransceiverState()</span><br><span>   : mRetrans(false), mNoiseLev(0.0), mNoises(NOISE_CNT), mPower(0.0)</span><br><span> {</span><br><span>@@ -437,12 +445,8 @@</span><br><span>       delete burst;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    if (stale_bursts_changed) {</span><br><span style="color: hsl(0, 100%, 40%);">-      thread_enable_cancel(false);</span><br><span style="color: hsl(0, 100%, 40%);">-      state->ctrs.chan = i;</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_signal_dispatch(SS_DEVICE, S_TRX_COUNTER_CHANGE, &state->ctrs);</span><br><span style="color: hsl(0, 100%, 40%);">-      thread_enable_cancel(true);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(120, 100%, 40%);">+    if (stale_bursts_changed)</span><br><span style="color: hsl(120, 100%, 40%);">+      dispatch_trx_rate_ctr_change(state, i);</span><br><span> </span><br><span>     TN = nowTime.TN();</span><br><span>     modFN = nowTime.FN() % state->fillerModulus[TN];</span><br><span>@@ -461,7 +465,7 @@</span><br><span>       }</span><br><span> </span><br><span>       delete burst;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(120, 100%, 40%);">+    } //else { rate_counter() }</span><br><span>   }</span><br><span> </span><br><span>   mRadioInterface->driveTransmitRadio(bursts, zeros);</span><br><span>@@ -1001,6 +1005,7 @@</span><br><span>   struct trxd_hdr_v01_dl *dl;</span><br><span>   char buffer[sizeof(*dl) + EDGE_BURST_NBITS];</span><br><span>   uint32_t fn;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t tn;</span><br><span> </span><br><span>   // check data socket</span><br><span>   msgLen = read(mDataSockets[chan], buffer, sizeof(buffer));</span><br><span>@@ -1029,6 +1034,7 @@</span><br><span> </span><br><span>   /* Convert TDMA FN to the host endianness */</span><br><span>   fn = osmo_load32be(&dl->common.fn);</span><br><span style="color: hsl(120, 100%, 40%);">+  tn = dl->common.tn;</span><br><span> </span><br><span>   /* Make sure we support the received header format */</span><br><span>   switch (dl->common.version) {</span><br><span>@@ -1044,14 +1050,45 @@</span><br><span>   LOGCHAN(chan, DTRXDDL, DEBUG) << "Rx TRXD message (hdr_ver=" << unsigned(dl->common.version)</span><br><span>     << "): fn=" << fn << ", tn=" << unsigned(dl->common.tn) << ", burst_len=" << burstLen;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  TransceiverState *state = &mStates[chan];</span><br><span style="color: hsl(120, 100%, 40%);">+  GSM::Time currTime = GSM::Time(fn, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Verify proper FN order in DL stream */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (state->first_dl_fn_rcv[tn]) {</span><br><span style="color: hsl(120, 100%, 40%);">+    int32_t delta = GSM::FNDelta(currTime.FN(), state->last_dl_time_rcv[tn].FN());</span><br><span style="color: hsl(120, 100%, 40%);">+    if (delta == 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* usual expected scenario, continue code flow */</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (delta == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGCHAN(chan, DTRXDDL, NOTICE) << "Rx TRXD msg with repeated FN " << currTime;</span><br><span style="color: hsl(120, 100%, 40%);">+      state->ctrs.tx_trxd_fn_repeated++;</span><br><span style="color: hsl(120, 100%, 40%);">+      dispatch_trx_rate_ctr_change(state, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+      return true;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (delta < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGCHAN(chan, DTRXDDL, NOTICE) << "Rx TRXD msg with previous FN " << currTime</span><br><span style="color: hsl(120, 100%, 40%);">+                                     << " vs last " << state->last_dl_time_rcv[tn];</span><br><span style="color: hsl(120, 100%, 40%);">+       state->ctrs.tx_trxd_fn_outoforder++;</span><br><span style="color: hsl(120, 100%, 40%);">+       dispatch_trx_rate_ctr_change(state, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Allow adding radio vector below, since it gets sorted in the queue */</span><br><span style="color: hsl(120, 100%, 40%);">+    } else { /* some FN was lost in the middle */</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGCHAN(chan, DTRXDDL, NOTICE) << "Rx TRXD msg with future FN " << currTime</span><br><span style="color: hsl(120, 100%, 40%);">+                                     << " vs last " << state->last_dl_time_rcv[tn]</span><br><span style="color: hsl(120, 100%, 40%);">+                                     << ", " << delta - 1 << " FN lost";</span><br><span style="color: hsl(120, 100%, 40%);">+      state->ctrs.tx_trxd_fn_skipped += delta - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      dispatch_trx_rate_ctr_change(state, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+    if (delta > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+      state->last_dl_time_rcv[tn] = currTime;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else { /* Initial check, simply store state */</span><br><span style="color: hsl(120, 100%, 40%);">+    state->first_dl_fn_rcv[tn] = true;</span><br><span style="color: hsl(120, 100%, 40%);">+    state->last_dl_time_rcv[tn] = currTime;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   BitVector newBurst(burstLen);</span><br><span>   BitVector::iterator itr = newBurst.begin();</span><br><span>   uint8_t *bufferItr = dl->soft_bits;</span><br><span>   while (itr < newBurst.end())</span><br><span>     *itr++ = *bufferItr++;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  GSM::Time currTime = GSM::Time(fn, dl->common.tn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   addRadioVector(chan, newBurst, dl->tx_att, currTime);</span><br><span> </span><br><span>   return true;</span><br><span>diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h</span><br><span>index 7ce5fa2..52748c1 100644</span><br><span>--- a/Transceiver52M/Transceiver.h</span><br><span>+++ b/Transceiver52M/Transceiver.h</span><br><span>@@ -86,6 +86,10 @@</span><br><span> </span><br><span>   /* counters */</span><br><span>   struct trx_counters ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Used to keep track of lost and out of order frames */</span><br><span style="color: hsl(120, 100%, 40%);">+  bool first_dl_fn_rcv[8];</span><br><span style="color: hsl(120, 100%, 40%);">+  GSM::Time last_dl_time_rcv[8];</span><br><span> };</span><br><span> </span><br><span> /** The Transceiver class, responsible for physical layer of basestation */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-trx/+/19205">change 19205</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-trx/+/19205"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ia34f7e7d780ad1e12f24638a07f05fe91f2afea5 </div>
<div style="display:none"> Gerrit-Change-Number: 19205 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>