<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/22265">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">hodec2: fix congestion resolution on dyn TS<br><br>For handover algorithm 2, properly figure out what effects the target<br>cell will see for the *other* TCH kind when a handover would occupy a<br>dynamic timeslot.<br><br>Before this, only TCH/F or TCH/H would be regarded at a time. This<br>introduces detection of whether a dynamic timeslot would be occupied by<br>a handover, and how losing one unused dynamic timeslot affects the<br>congestion situation for the TCH kind that is not targeted by the<br>handover.<br><br>In other words, if a handover to TCH/F causes congestion in TCH/H<br>because of a dynamic timeslot becoming occupied, the handover will not<br>be performed. Before this, oscillation situations could occur.<br><br>A subsequent patch will do the same for congestion balancing.<br><br>Related: SYS#5297<br>Change-Id: I1536b60f03cb0aeb6ba14a72b518aec82fa572fe<br>---<br>M src/osmo-bsc/handover_decision_2.c<br>M tests/handover/test_dyn_ts_congestion_tch_f_vs_tch_h.ho_vty<br>2 files changed, 37 insertions(+), 20 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/65/22265/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c</span><br><span>index 0362c9b..131a309 100644</span><br><span>--- a/src/osmo-bsc/handover_decision_2.c</span><br><span>+++ b/src/osmo-bsc/handover_decision_2.c</span><br><span>@@ -40,6 +40,7 @@</span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/bts.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/lchan_select.h></span><br><span> </span><br><span> #define LOGPHOBTS(bts, level, fmt, args...) \</span><br><span>     LOGP(DHODEC, level, "(BTS %u) " fmt, bts->nr, ## args)</span><br><span>@@ -118,6 +119,9 @@</span><br><span>            int min_free_tchf;</span><br><span>           int free_tchh;</span><br><span>               int min_free_tchh;</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Effects of occupying a dynamic timeslot: */</span><br><span style="color: hsl(120, 100%, 40%);">+                int next_tchf_reduces_tchh;</span><br><span style="color: hsl(120, 100%, 40%);">+           int next_tchh_reduces_tchf;</span><br><span>  } target;</span><br><span> };</span><br><span> </span><br><span>@@ -637,11 +641,15 @@</span><br><span>  /* the minimum free timeslots that are defined for this cell must</span><br><span>     * be maintained _after_ handover/assignment */</span><br><span>      if (requirement & REQUIREMENT_A_TCHF) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (c->target.free_tchf - 1 >= c->target.min_free_tchf)</span><br><span style="color: hsl(120, 100%, 40%);">+              if (c->target.free_tchf - 1 >= c->target.min_free_tchf</span><br><span style="color: hsl(120, 100%, 40%);">+                   && (!c->target.next_tchf_reduces_tchh</span><br><span style="color: hsl(120, 100%, 40%);">+                  || c->target.free_tchh - c->target.next_tchf_reduces_tchh >= c->target.min_free_tchh))</span><br><span>                   requirement |= REQUIREMENT_B_TCHF;</span><br><span>   }</span><br><span>    if (requirement & REQUIREMENT_A_TCHH) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (c->target.free_tchh - 1 >= c->target.min_free_tchh)</span><br><span style="color: hsl(120, 100%, 40%);">+              if (c->target.free_tchh - 1 >= c->target.min_free_tchh</span><br><span style="color: hsl(120, 100%, 40%);">+                   && (!c->target.next_tchh_reduces_tchf</span><br><span style="color: hsl(120, 100%, 40%);">+                  || c->target.free_tchf - c->target.next_tchh_reduces_tchf >= c->target.min_free_tchf))</span><br><span>                   requirement |= REQUIREMENT_B_TCHH;</span><br><span>   }</span><br><span> </span><br><span>@@ -894,6 +902,8 @@</span><br><span> </span><br><span> static void candidate_set_free_tch(struct ho_candidate *c)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_lchan *next_lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      c->current.free_tch = bts_count_free_ts(c->current.bts, c->current.lchan->ts->pchan_is);</span><br><span>      switch (c->current.lchan->ts->pchan_is) {</span><br><span>   case GSM_PCHAN_TCH_F:</span><br><span>@@ -909,6 +919,21 @@</span><br><span>         c->target.min_free_tchf = ho_get_hodec2_tchf_min_slots(c->target.bts->ho);</span><br><span>  c->target.free_tchh = bts_count_free_ts(c->target.bts, GSM_PCHAN_TCH_H);</span><br><span>       c->target.min_free_tchh = ho_get_hodec2_tchh_min_slots(c->target.bts->ho);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Would the next TCH/F lchan convert a dynamic timeslot that currently counts for free TCH/H timeslots? */</span><br><span style="color: hsl(120, 100%, 40%);">+   next_lchan = lchan_avail_by_type(c->target.bts, GSM_LCHAN_TCH_F);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (next_lchan && next_lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_TCH_H_PDCH)</span><br><span style="color: hsl(120, 100%, 40%);">+          c->target.next_tchf_reduces_tchh = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+      else</span><br><span style="color: hsl(120, 100%, 40%);">+          c->target.next_tchf_reduces_tchh = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Would the next TCH/H lchan convert a dynamic timeslot that currently counts for free TCH/F timeslots? */</span><br><span style="color: hsl(120, 100%, 40%);">+   next_lchan = lchan_avail_by_type(c->target.bts, GSM_LCHAN_TCH_H);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (next_lchan && next_lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_TCH_H_PDCH</span><br><span style="color: hsl(120, 100%, 40%);">+       && next_lchan->ts->pchan_is != GSM_PCHAN_TCH_H)</span><br><span style="color: hsl(120, 100%, 40%);">+             c->target.next_tchh_reduces_tchf = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      else</span><br><span style="color: hsl(120, 100%, 40%);">+          c->target.next_tchh_reduces_tchf = 0;</span><br><span> }</span><br><span> </span><br><span> /* add candidate for re-assignment within the current cell */</span><br><span>diff --git a/tests/handover/test_dyn_ts_congestion_tch_f_vs_tch_h.ho_vty b/tests/handover/test_dyn_ts_congestion_tch_f_vs_tch_h.ho_vty</span><br><span>index bc2c884..c5890a5 100644</span><br><span>--- a/tests/handover/test_dyn_ts_congestion_tch_f_vs_tch_h.ho_vty</span><br><span>+++ b/tests/handover/test_dyn_ts_congestion_tch_f_vs_tch_h.ho_vty</span><br><span>@@ -20,12 +20,8 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> meas-rep lchan 0 0 1 0 rxlev 20 rxqual 0 ta 0 neighbors 40</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL: should not handover because that results in congestion on TCH/H in bts 1</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 1 0 to lchan 1 0 5 0</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - pdch pdch pdch *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F TCH/F TCH/F TCH/HH TCH/F pdch *</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+# no handover because that results in congestion on TCH/H in bts 1</span><br><span style="color: hsl(120, 100%, 40%);">+expect-no-chan</span><br><span> </span><br><span> ###</span><br><span> </span><br><span>@@ -34,11 +30,9 @@</span><br><span> meas-rep lchan * * * * rxlev 40 rxqual 0 ta 0 neighbors 30</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL: really weird: handover one TCH/H to the same cell to TCH/F, taking up another dyn TS.</span><br><span style="color: hsl(0, 100%, 40%);">-# TCH/H congestion hence actually gets worse.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 1 0 4 1 to lchan 1 0 6 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - pdch pdch pdch *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F TCH/F TCH/F TCH/H- TCH/F TCH/F *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 1 0 4 1 to lchan 0 0 4 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * - - - TCH/H- pdch pdch *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * TCH/F TCH/F TCH/F TCH/H- TCH/F pdch *</span><br><span> </span><br><span> </span><br><span> ###</span><br><span>@@ -65,12 +59,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> meas-rep lchan 0 * * * rxlev 30 rxqual 0 ta 0 neighbors 40</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL: back to bts 1 because of rxlev, plus moving TCH/H to TCH/F!?</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 4 0 to lchan 1 0 4 0</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - pdch pdch pdch *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F TCH/F TCH/F TCH/F TCH/F TCH/F *</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+# no HO because the target is congested on TCH/H. Moving to TCH/F would also</span><br><span style="color: hsl(120, 100%, 40%);">+# reduce TCH/H lchans because it would convert another dyn TS.</span><br><span style="color: hsl(120, 100%, 40%);">+expect-no-chan</span><br><span> </span><br><span> ###</span><br><span> </span><br><span>@@ -78,5 +69,6 @@</span><br><span> set-ts-use trx 1 0 states * TCH/F TCH/F TCH/F TCH/F TCH/F TCH/F *</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(120, 100%, 40%);">+# FAIL: TCH/F occupy dynamic timeslots -- should hand over to bts 0 to free a</span><br><span style="color: hsl(120, 100%, 40%);">+# dyn TS and reduce TCH/H congestion.</span><br><span> expect-no-chan</span><br><span style="color: hsl(0, 100%, 40%);">-# Stable situation now only because TCH/F has min-free-slots set to 0</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/22265">change 22265</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-bsc/+/22265"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1536b60f03cb0aeb6ba14a72b518aec82fa572fe </div>
<div style="display:none"> Gerrit-Change-Number: 22265 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>