<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/20919">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">alloc_algo_b: Select TRX with least assigned TFIs during TBF alloc<br><br>Before this patch, it would always allocate all TBFs on the first TRX<br>until all TFIs were filled, then second, and so on. But it would<br>actually fail around 8th MS requesting an UL TBF because despite a TFI<br>was successfuly assigned, because all USFs were already exhausted for<br>that PDCH.<br><br>Related: OS#1775<br>Change-Id: Iccfc8acfbfdc258ed16cc5af01f12b376fe73b72<br>---<br>M src/bts.cpp<br>M tests/tbf/TbfTest.cpp<br>2 files changed, 53 insertions(+), 30 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/19/20919/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/bts.cpp b/src/bts.cpp</span><br><span>index da62b30..833dcca 100644</span><br><span>--- a/src/bts.cpp</span><br><span>+++ b/src/bts.cpp</span><br><span>@@ -536,18 +536,51 @@</span><br><span> return m_bts.trx[trx].pdch[ts].ul_tbf_by_tfi(tfi);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t trx_count_free_tfi(const struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint32_t *free_tfi_mask)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t ts;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned i;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t free_tfi = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool has_pdch = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t mask = NO_FREE_TFI;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (ts = 0; ts < 8; ts++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdch = &trx->pdch[ts];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pdch->is_enabled())</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ has_pdch = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ mask &= ~pdch->assigned_tfi(dir);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!has_pdch || !mask) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *free_tfi_mask = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *free_tfi_mask = mask;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Count free tfis and return */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < sizeof(uint32_t)*8 ; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if(mask & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ free_tfi++;</span><br><span style="color: hsl(120, 100%, 40%);">+ mask >>= 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return free_tfi;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*</span><br><span style="color: hsl(0, 100%, 40%);">- * Search for free TFI and return TFI, TRX.</span><br><span style="color: hsl(0, 100%, 40%);">- * This method returns the first TFI that is currently not used in any PDCH of</span><br><span style="color: hsl(0, 100%, 40%);">- * a TRX. The first TRX that contains such an TFI is returned. Negative values</span><br><span style="color: hsl(0, 100%, 40%);">- * indicate errors.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Search for free TFI and return TFI, TRX. This method returns the first TFI</span><br><span style="color: hsl(120, 100%, 40%);">+ * that is currently not used in any PDCH of a the TRX with least TFIs currently</span><br><span style="color: hsl(120, 100%, 40%);">+ * assigned. Negative values indicate errors.</span><br><span> */</span><br><span> int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- const struct gprs_rlcmac_pdch *pdch;</span><br><span style="color: hsl(0, 100%, 40%);">- uint32_t free_tfis;</span><br><span style="color: hsl(0, 100%, 40%);">- bool has_pdch = false;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t trx_from, trx_to, trx, ts, tfi;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t trx_from, trx_to, trx, tfi;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t best_trx_nr = 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t best_cnt = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t best_mask = 0;</span><br><span> </span><br><span> if (use_trx >= 0 && use_trx < 8)</span><br><span> trx_from = trx_to = use_trx;</span><br><span>@@ -558,47 +591,36 @@</span><br><span> </span><br><span> /* find a TFI that is unused on all PDCH */</span><br><span> for (trx = trx_from; trx <= trx_to; trx++) {</span><br><span style="color: hsl(0, 100%, 40%);">- bool trx_has_pdch = false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- free_tfis = NO_FREE_TFI;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (ts = 0; ts < 8; ts++) {</span><br><span style="color: hsl(0, 100%, 40%);">- pdch = &m_bts.trx[trx].pdch[ts];</span><br><span style="color: hsl(0, 100%, 40%);">- if (!pdch->is_enabled())</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- free_tfis &= ~pdch->assigned_tfi(dir);</span><br><span style="color: hsl(0, 100%, 40%);">- trx_has_pdch = true;</span><br><span style="color: hsl(0, 100%, 40%);">- has_pdch = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t tmp_mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t tmp_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+ tmp_cnt = trx_count_free_tfi(&m_bts.trx[trx], dir, &tmp_mask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tmp_cnt > best_cnt) {</span><br><span style="color: hsl(120, 100%, 40%);">+ best_cnt = tmp_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+ best_mask = tmp_mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ best_trx_nr = trx;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- if (trx_has_pdch && free_tfis)</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- free_tfis = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (!has_pdch) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH available.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -EINVAL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!free_tfis) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (best_trx_nr == 0xff || best_cnt == 0) {</span><br><span> LOGP(DRLCMAC, LOGL_NOTICE, "No TFI available (suggested TRX: %d).\n", use_trx);</span><br><span> return -EBUSY;</span><br><span> }</span><br><span> </span><br><span> </span><br><span> LOGP(DRLCMAC, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "Searching for first unallocated TFI: TRX=%d\n", trx);</span><br><span style="color: hsl(120, 100%, 40%);">+ "Searching for first unallocated TFI: TRX=%d\n", best_trx_nr);</span><br><span> </span><br><span> /* find the first */</span><br><span> for (tfi = 0; tfi < 32; tfi++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (free_tfis & 1 << tfi)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (best_mask & 1 << tfi)</span><br><span> break;</span><br><span> }</span><br><span> </span><br><span> OSMO_ASSERT(tfi < 32);</span><br><span> </span><br><span> LOGP(DRLCMAC, LOGL_DEBUG, " Found TFI=%d.\n", tfi);</span><br><span style="color: hsl(0, 100%, 40%);">- *_trx = trx;</span><br><span style="color: hsl(120, 100%, 40%);">+ *_trx = best_trx_nr;</span><br><span> return tfi;</span><br><span> }</span><br><span> </span><br><span>diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp</span><br><span>index 2b5bda5..8a6789b 100644</span><br><span>--- a/tests/tbf/TbfTest.cpp</span><br><span>+++ b/tests/tbf/TbfTest.cpp</span><br><span>@@ -197,6 +197,7 @@</span><br><span> tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);</span><br><span> OSMO_ASSERT(tfi >= 0);</span><br><span> dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(dl_tbf);</span><br><span> dl_tbf->set_ta(0);</span><br><span> check_tbf(dl_tbf);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/20919">change 20919</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-pcu/+/20919"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-pcu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Iccfc8acfbfdc258ed16cc5af01f12b376fe73b72 </div>
<div style="display:none"> Gerrit-Change-Number: 20919 </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>