pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-pcu/+/32358 )

Change subject: ms: Make ms_{attach,detach}_tbf expectancies more robust
......................................................................

ms: Make ms_{attach,detach}_tbf expectancies more robust

* Make sure that the tbf being attached has already the MS assigned.
* Check no re-attaching of alredy attached TBF ever happens.
* Document and early skip case where a non-attached TBF detach is
  attempted.
* Avoid recursive call mess to tbf_set_ms(tbf, NULL); during detach.
* MsTest needs to be modified since it uses fake TBF objects which use
  different set of calls than the regular TBFs in osmo-pcu. Since the
ul_tbf object is reused, it needs to be assigned ul_tbf->ms again before
re-assigning it, as per what happens usually in tbf_set_ms() in
osmo-pcu.

Change-Id: Ia18fe2de1fb3bf72f530157e5f30de64f2b11e12
---
M src/gprs_ms.c
M tests/ms/MsTest.cpp
M tests/ms/MsTest.err
3 files changed, 60 insertions(+), 31 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve
  osmith: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved




diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index 357470b..da50426 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -348,11 +348,30 @@
        }
 }

+/* If a TBF is attached to an MS, it is either in ms->{dl,ul}_tbf or in 
ms->old_tbfs list */
+static bool ms_tbf_is_attached(const struct GprsMs *ms, const struct 
gprs_rlcmac_tbf *tbf)
+{
+       const struct llist_item *pos;
+       OSMO_ASSERT(ms);
+       OSMO_ASSERT(tbf);
+       OSMO_ASSERT(tbf_ms(tbf) == ms);
+
+       if (tbf == ul_tbf_as_tbf_const(ms->ul_tbf))
+               return true;
+
+       if (tbf == dl_tbf_as_tbf_const(ms->dl_tbf))
+               return true;
+
+       llist_for_each_entry(pos, &ms->old_tbfs, list) {
+               const struct gprs_rlcmac_tbf *tmp_tbf = (struct gprs_rlcmac_tbf 
*)pos->entry;
+               if (tmp_tbf == tbf)
+                       return true;
+       }
+       return false;
+}
+
 static void ms_attach_ul_tbf(struct GprsMs *ms, struct gprs_rlcmac_ul_tbf *tbf)
 {
-       if (ms->ul_tbf == tbf)
-               return;
-
        LOGPMS(ms, DRLCMAC, LOGL_INFO, "Attaching UL TBF: %s\n", 
tbf_name((struct gprs_rlcmac_tbf *)tbf));

        ms_ref(ms, __func__);
@@ -369,9 +388,6 @@

 static void ms_attach_dl_tbf(struct GprsMs *ms, struct gprs_rlcmac_dl_tbf *tbf)
 {
-       if (ms->dl_tbf == tbf)
-               return;
-
        LOGPMS(ms, DRLCMAC, LOGL_INFO, "Attaching DL TBF: %s\n", 
tbf_name((struct gprs_rlcmac_tbf *)tbf));

        ms_ref(ms, __func__);
@@ -390,6 +406,7 @@
 {
        OSMO_ASSERT(ms);
        OSMO_ASSERT(tbf);
+       OSMO_ASSERT(!ms_tbf_is_attached(ms, tbf));

        if (tbf_direction(tbf) == GPRS_RLCMAC_DL_TBF)
                ms_attach_dl_tbf(ms, tbf_as_dl_tbf(tbf));
@@ -399,34 +416,26 @@

 void ms_detach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
 {
-       if (tbf == (struct gprs_rlcmac_tbf *)(ms->ul_tbf)) {
+       OSMO_ASSERT(tbf_ms(tbf) == ms);
+
+       /* In general this should not happen, but it can happen if during TBF
+        * allocation something fails before tbf->setup() called 
ms_attach_tbf(). */
+       if (!ms_tbf_is_attached(ms, tbf))
+               return;
+
+       if (tbf == ul_tbf_as_tbf(ms->ul_tbf)) {
                ms->ul_tbf = NULL;
-       } else if (tbf == (struct gprs_rlcmac_tbf *)(ms->dl_tbf)) {
+       } else if (tbf == dl_tbf_as_tbf(ms->dl_tbf)) {
                ms->dl_tbf = NULL;
        } else {
-               bool found = false;
-
-               struct llist_item *pos, *tmp;
-               llist_for_each_entry_safe(pos, tmp, &ms->old_tbfs, list) {
-                       struct gprs_rlcmac_tbf *tmp_tbf = (struct 
gprs_rlcmac_tbf *)pos->entry;
-                       if (tmp_tbf == tbf) {
-                               llist_del(&pos->list);
-                               found = true;
-                               break;
-                       }
-               }
-
-               /* Protect against recursive calls via set_ms() */
-               if (!found)
-                       return;
+               /* We know from ms_tbf_is_attached()==true check above that tbf
+                * is in ms->old_tbfs, no need to look it up again. */
+               llist_del(tbf_ms_list(tbf));
        }

        LOGPMS(ms, DRLCMAC, LOGL_INFO, "Detaching TBF: %s\n",
               tbf_name(tbf));

-       if (tbf_ms(tbf) == ms)
-               tbf_set_ms(tbf, NULL);
-
        if (!ms->dl_tbf && !ms->ul_tbf) {
                ms_set_reserved_slots(ms, NULL, 0, 0);
                ms->first_common_ts = NULL;
diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp
index a8febd0..40e8381 100644
--- a/tests/ms/MsTest.cpp
+++ b/tests/ms/MsTest.cpp
@@ -443,7 +443,7 @@
        OSMO_ASSERT(ms != NULL);
        ul_tbf = alloc_ul_tbf(bts, ms);
        ms_attach_tbf(ms, ul_tbf);
-       ms_detach_tbf(ms, ul_tbf);
+       tbf_set_ms(ul_tbf, NULL);
        ms = bts_get_ms_by_tlli(bts, tlli + 0, GSM_RESERVED_TMSI);
        OSMO_ASSERT(ms == NULL);
        ms = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
@@ -452,8 +452,8 @@
        /* delete ms */
        ms = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
        OSMO_ASSERT(ms != NULL);
-       ms_attach_tbf(ms, ul_tbf);
-       ms_detach_tbf(ms, ul_tbf);
+       tbf_set_ms(ul_tbf, ms);
+       tbf_set_ms(ul_tbf, NULL);
        ms = bts_get_ms_by_tlli(bts, tlli + 1, GSM_RESERVED_TMSI);
        OSMO_ASSERT(ms == NULL);

diff --git a/tests/ms/MsTest.err b/tests/ms/MsTest.err
index 3d271ae..3f2f520 100644
--- a/tests/ms/MsTest.err
+++ b/tests/ms/MsTest.err
@@ -63,10 +63,10 @@
 MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): - 
ms_attach_ul_tbf: now used by 0 (-)
 MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Detaching TBF: 
TBF(UL:STATE-NEW:GPRS:IMSI-001001987654321:TLLI-0xffeeddbb)
 MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Destroying MS object
-MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Attaching UL TBF: 
TBF(UL:STATE-NEW:GPRS)
+MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Attaching UL TBF: 
TBF(UL:STATE-NEW:GPRS:IMSI-001001987654322:TLLI-0xffeeddbc)
 MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0): + ms_attach_ul_tbf: 
now used by 1 (ms_attach_ul_tbf)
 MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0:UL): - 
ms_attach_ul_tbf: now used by 0 (-)
-MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Detaching TBF: 
TBF(UL:STATE-NEW:GPRS)
+MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Detaching TBF: 
TBF(UL:STATE-NEW:GPRS:IMSI-001001987654322:TLLI-0xffeeddbc)
 MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Destroying MS object
 Creating MS object
 Modifying MS object, UL TLLI: 0xffffffff -> 0xffeeddbb, not yet confirmed

--
To view, visit https://gerrit.osmocom.org/c/osmo-pcu/+/32358
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: Ia18fe2de1fb3bf72f530157e5f30de64f2b11e12
Gerrit-Change-Number: 32358
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-CC: fixeria <[email protected]>
Gerrit-MessageType: merged

Reply via email to