<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-pcu/+/23520">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Pick unreserved UL FN when allocating an SBA<br><br>Make sure an unreserved FN is picked and reserved when allocating and<br>scheduling an SBA.<br>In practice this has no change in behavior right now, since anyway using<br>an offset of 52 FNs ensure no USF or POLL has alredy been scheduled that<br>far in the future. Since it's also impossible to allocate more than 1<br>SBA per PDCH and RTS FN, we are also save about multiple SBAs being<br>allocated, because we use a hardcoded fofset of 52.<br>However, that could change in the future, when we dynamically tweak the<br>current offset of 52 FN based on information from BTS about its AGCH<br>queue load:<br>* If load is high, we may need to increase the offset since it<br>will take more time for the BTS to transmit the TBF and hence we must<br>reserve a TBF starting time further in the future (higher FN).<br>* If load turns low, we may schedule next SBA a bit more nearby in time<br>  than the previously allocated SBA, hence here there could be a<br>  collision.<br><br>Related: OS#5020<br>Change-Id: I2d4e21e2307de6c17748e8da5c7e149c947a7eb9<br>---<br>M src/pdch_ul_controller.c<br>M src/pdch_ul_controller.h<br>M src/sba.c<br>M tests/ulc/PdchUlcTest.cpp<br>M tests/ulc/PdchUlcTest.ok<br>5 files changed, 64 insertions(+), 3 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/20/23520/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/pdch_ul_controller.c b/src/pdch_ul_controller.c</span><br><span>index e6e22a2..1ead3e9 100644</span><br><span>--- a/src/pdch_ul_controller.c</span><br><span>+++ b/src/pdch_ul_controller.c</span><br><span>@@ -128,6 +128,29 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Get next free (unreserved) FN which is not located in time before "start_fn" */</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t pdch_ulc_get_next_free_fn(struct pdch_ulc *ulc, uint32_t start_fn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct rb_node *node;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct pdch_ulc_node *it;</span><br><span style="color: hsl(120, 100%, 40%);">+     int res;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t check_fn = start_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       for (node = rb_first(&ulc->tree_root); node; node = rb_next(node)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           it = container_of(node, struct pdch_ulc_node, node);</span><br><span style="color: hsl(120, 100%, 40%);">+          res = fn_cmp(it->fn, check_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (res > 0) { /* it->fn AFTER check_fn */</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* Next reserved FN is passed check_fn, hence it means check_fn is free */</span><br><span style="color: hsl(120, 100%, 40%);">+                    return check_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* if it->fn < check_fn, simply continue iterating, we want to reach at least check_fn */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (res == 0)/* it->fn == fn */</span><br><span style="color: hsl(120, 100%, 40%);">+                    check_fn = fn_next_block(check_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+           /* if it->fn < check_fn, simply continue iterating, we want to reach at least check_fn */</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     return check_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct pdch_ulc_node *_alloc_node(struct pdch_ulc *ulc, uint32_t fn)</span><br><span> {</span><br><span>    struct pdch_ulc_node *node;</span><br><span>diff --git a/src/pdch_ul_controller.h b/src/pdch_ul_controller.h</span><br><span>index 731cbe1..5339e90 100644</span><br><span>--- a/src/pdch_ul_controller.h</span><br><span>+++ b/src/pdch_ul_controller.h</span><br><span>@@ -71,6 +71,7 @@</span><br><span> bool pdch_ulc_fn_is_free(struct pdch_ulc *ulc, uint32_t fn);</span><br><span> </span><br><span> int pdch_ulc_get_next_free_rrbp_fn(struct pdch_ulc *ulc, uint32_t fn, uint32_t *poll_fn, unsigned int *rrbp);</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t pdch_ulc_get_next_free_fn(struct pdch_ulc *ulc, uint32_t start_fn);</span><br><span> </span><br><span> struct pdch_ulc_node *pdch_ulc_get_node(struct pdch_ulc *ulc, uint32_t fn);</span><br><span> struct pdch_ulc_node *pdch_ulc_pop_node(struct pdch_ulc *ulc, uint32_t fn);</span><br><span>diff --git a/src/sba.c b/src/sba.c</span><br><span>index 4b878b7..fcbd25e 100644</span><br><span>--- a/src/sba.c</span><br><span>+++ b/src/sba.c</span><br><span>@@ -57,15 +57,18 @@</span><br><span> struct gprs_rlcmac_sba *sba_alloc(void *ctx, struct gprs_rlcmac_pdch *pdch, uint8_t ta)</span><br><span> {</span><br><span>     struct gprs_rlcmac_sba *sba;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t start_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         sba = talloc_zero(ctx, struct gprs_rlcmac_sba);</span><br><span>      if (!sba)</span><br><span>            return NULL;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* TODO: Increase start_fn dynamically based on AGCH queue load in the BTS: */</span><br><span style="color: hsl(120, 100%, 40%);">+        start_fn = next_fn(pdch->last_rts_fn, AGCH_START_OFFSET);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       sba->pdch = pdch;</span><br><span>         sba->ta = ta;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* TODO: request ULC for next available FN instead of hardcoded AGCH_START_OFFSET */</span><br><span style="color: hsl(0, 100%, 40%);">-    sba->fn = next_fn(pdch->last_rts_fn, AGCH_START_OFFSET);</span><br><span style="color: hsl(120, 100%, 40%);">+        sba->fn = pdch_ulc_get_next_free_fn(pdch->ulc, start_fn);</span><br><span> </span><br><span>  pdch_ulc_reserve_sba(pdch->ulc, sba);</span><br><span>     return sba;</span><br><span>diff --git a/tests/ulc/PdchUlcTest.cpp b/tests/ulc/PdchUlcTest.cpp</span><br><span>index 0099101..f0e8dd9 100644</span><br><span>--- a/tests/ulc/PdchUlcTest.cpp</span><br><span>+++ b/tests/ulc/PdchUlcTest.cpp</span><br><span>@@ -212,6 +212,30 @@</span><br><span>  printf("=== end: %s ===\n", __FUNCTION__);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void test_next_free_fn_sba()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("=== start: %s ===\n", __FUNCTION__);</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_pdch *pdch = &bts->trx[0].pdch[0];</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gprs_rlcmac_sba *sba1, *sba2, *sba3, *sba4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  pdch->last_rts_fn = 52;</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("*** ALLOC 1 SBA FN=%" PRIu32 ":\n", pdch->last_rts_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        sba1 = sba_alloc(bts, pdch, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       print_ulc_nodes(pdch->ulc);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pdch->last_rts_fn = 65;</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("*** ALLOC 3 SBA FN=%" PRIu32 ":\n", pdch->last_rts_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+        sba2 = sba_alloc(bts, pdch, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       sba3 = sba_alloc(bts, pdch, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       sba4 = sba_alloc(bts, pdch, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       print_ulc_nodes(pdch->ulc);</span><br><span style="color: hsl(120, 100%, 40%);">+        (void)sba1; (void)sba2; (void)sba3; (void)sba4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("=== end: %s ===\n", __FUNCTION__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span>    tall_pcu_ctx = talloc_named_const(NULL, 1, "pdch_ulc test context");</span><br><span>@@ -231,6 +255,7 @@</span><br><span> </span><br><span>     test_reserve_multiple();</span><br><span>     test_fn_wrap_around();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_next_free_fn_sba();</span><br><span> </span><br><span>         talloc_free(the_pcu);</span><br><span>        return EXIT_SUCCESS;</span><br><span>diff --git a/tests/ulc/PdchUlcTest.ok b/tests/ulc/PdchUlcTest.ok</span><br><span>index f20fb30..5bab5cc 100644</span><br><span>--- a/tests/ulc/PdchUlcTest.ok</span><br><span>+++ b/tests/ulc/PdchUlcTest.ok</span><br><span>@@ -247,3 +247,12 @@</span><br><span> FN=39 type=POLL</span><br><span> *** EXPIRE FN=43:</span><br><span> === end: test_fn_wrap_around ===</span><br><span style="color: hsl(120, 100%, 40%);">+=== start: test_next_free_fn_sba ===</span><br><span style="color: hsl(120, 100%, 40%);">+*** ALLOC 1 SBA FN=52:</span><br><span style="color: hsl(120, 100%, 40%);">+FN=104 type=SBA</span><br><span style="color: hsl(120, 100%, 40%);">+*** ALLOC 3 SBA FN=65:</span><br><span style="color: hsl(120, 100%, 40%);">+FN=104 type=SBA</span><br><span style="color: hsl(120, 100%, 40%);">+FN=117 type=SBA</span><br><span style="color: hsl(120, 100%, 40%);">+FN=121 type=SBA</span><br><span style="color: hsl(120, 100%, 40%);">+FN=125 type=SBA</span><br><span style="color: hsl(120, 100%, 40%);">+=== end: test_next_free_fn_sba ===</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-pcu/+/23520">change 23520</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/+/23520"/><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: I2d4e21e2307de6c17748e8da5c7e149c947a7eb9 </div>
<div style="display:none"> Gerrit-Change-Number: 23520 </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>