pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33551 )
Change subject: rlcmac: Rework tbf destructor to signal free() to its gre object ......................................................................
rlcmac: Rework tbf destructor to signal free() to its gre object
This will be needed in follow-up patches for the MS to trigger actions when TBFs are freed (like going back to IDLE mode, or start packet-access-procedure).
Change-Id: I72959e27f2f62c84218d740cfb9e396d70562929 --- M include/osmocom/gprs/rlcmac/gre.h M src/rlcmac/gre.c M src/rlcmac/tbf.c M src/rlcmac/tbf_dl.c M src/rlcmac/tbf_ul.c 5 files changed, 53 insertions(+), 8 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/51/33551/1
diff --git a/include/osmocom/gprs/rlcmac/gre.h b/include/osmocom/gprs/rlcmac/gre.h index 3afeadc..c976b4a 100644 --- a/include/osmocom/gprs/rlcmac/gre.h +++ b/include/osmocom/gprs/rlcmac/gre.h @@ -7,6 +7,7 @@
struct gprs_rlcmac_dl_tbf; struct gprs_rlcmac_ul_tbf; +struct gprs_rlcmac_tbf;
struct gprs_rlcmac_entity { struct llist_head entry; /* item in (struct gprs_rlcmac_ctx)->gre_list */ @@ -37,5 +38,9 @@
struct msgb *gprs_rlcmac_gre_create_pkt_ctrl_ack(const struct gprs_rlcmac_entity *gre);
+void gprs_rlcmac_entity_dl_tbf_freed(struct gprs_rlcmac_entity *gre, const struct gprs_rlcmac_dl_tbf *ul_tbf); +void gprs_rlcmac_entity_ul_tbf_freed(struct gprs_rlcmac_entity *gre, const struct gprs_rlcmac_ul_tbf *ul_tbf); + + #define LOGGRE(gre, level, fmt, args...) \ LOGRLCMAC(level, "GRE(%08x) " fmt, (gre)->tlli, ## args) diff --git a/src/rlcmac/gre.c b/src/rlcmac/gre.c index e728695..6340437 100644 --- a/src/rlcmac/gre.c +++ b/src/rlcmac/gre.c @@ -79,6 +79,22 @@ talloc_free(gre); }
+/* Called by dl_tbf destructor to inform the DL TBF pointer has been freed. + * Hence memory pointed by "dl_tbf" is already freed and shall not be accessed. */ +void gprs_rlcmac_entity_dl_tbf_freed(struct gprs_rlcmac_entity *gre, const struct gprs_rlcmac_dl_tbf *dl_tbf) +{ + if (gre->dl_tbf == dl_tbf) + gre->dl_tbf = NULL; +} + +/* Called by ul_tbf destructor to inform the UL TBF pointer has been freed. + * Hence memory pointed by "ul_tbf" is already freed and shall not be accessed. */ +void gprs_rlcmac_entity_ul_tbf_freed(struct gprs_rlcmac_entity *gre, const struct gprs_rlcmac_ul_tbf *ul_tbf) +{ + if (gre->ul_tbf == ul_tbf) + gre->ul_tbf = NULL; +} + /* TS 44.060 5.3 In packet idle mode: * - no temporary block flow (TBF) exists.. * - the mobile station monitors the relevant paging subchannels on CCCH. In packet diff --git a/src/rlcmac/tbf.c b/src/rlcmac/tbf.c index 2168801..178f2fe 100644 --- a/src/rlcmac/tbf.c +++ b/src/rlcmac/tbf.c @@ -40,6 +40,7 @@ gprs_rlcmac_pdch_ulc_release_tbf(g_rlcmac_ctx->sched.ulc[i], tbf); }
+/* Comodity function to call required ul/dl tbf function: */ void gprs_rlcmac_tbf_free(struct gprs_rlcmac_tbf *tbf) { if (tbf->direction == GPRS_RLCMAC_TBF_DIR_UL) diff --git a/src/rlcmac/tbf_dl.c b/src/rlcmac/tbf_dl.c index 77110a9..570b0d7 100644 --- a/src/rlcmac/tbf_dl.c +++ b/src/rlcmac/tbf_dl.c @@ -61,11 +61,14 @@
void gprs_rlcmac_dl_tbf_free(struct gprs_rlcmac_dl_tbf *dl_tbf) { + struct gprs_rlcmac_tbf *tbf; + struct gprs_rlcmac_entity *gre; + if (!dl_tbf) return;
- if (dl_tbf->tbf.gre->dl_tbf == dl_tbf) - dl_tbf->tbf.gre->dl_tbf = NULL; + tbf = dl_tbf_as_tbf(dl_tbf); + gre = tbf->gre;
msgb_free(dl_tbf->llc_rx_msg); dl_tbf->llc_rx_msg = NULL; @@ -78,8 +81,10 @@
gprs_rlcmac_tbf_dl_fsm_destructor(dl_tbf);
- gprs_rlcmac_tbf_destructor(dl_tbf_as_tbf(dl_tbf)); + gprs_rlcmac_tbf_destructor(tbf); talloc_free(dl_tbf); + /* Inform the MS that the TBF pointer has been freed: */ + gprs_rlcmac_entity_dl_tbf_freed(gre, dl_tbf); }
diff --git a/src/rlcmac/tbf_ul.c b/src/rlcmac/tbf_ul.c index d83c609..d9cd04a 100644 --- a/src/rlcmac/tbf_ul.c +++ b/src/rlcmac/tbf_ul.c @@ -69,19 +69,22 @@
void gprs_rlcmac_ul_tbf_free(struct gprs_rlcmac_ul_tbf *ul_tbf) { + struct gprs_rlcmac_tbf *tbf; + struct gprs_rlcmac_entity *gre; + if (!ul_tbf) return;
+ tbf = ul_tbf_as_tbf(ul_tbf); + gre = tbf->gre; + if (ul_tbf->countdown_proc.llc_queue) { - gprs_rlcmac_llc_queue_merge_prepend(ul_tbf->tbf.gre->llc_queue, + gprs_rlcmac_llc_queue_merge_prepend(gre->llc_queue, ul_tbf->countdown_proc.llc_queue); gprs_rlcmac_llc_queue_free(ul_tbf->countdown_proc.llc_queue); ul_tbf->countdown_proc.llc_queue = NULL; }
- if (ul_tbf->tbf.gre->ul_tbf == ul_tbf) - ul_tbf->tbf.gre->ul_tbf = NULL; - talloc_free(ul_tbf->llc_tx_msg);
gprs_rlcmac_rlc_block_store_free(ul_tbf->blkst); @@ -93,8 +96,10 @@ gprs_rlcmac_tbf_ul_ass_fsm_destructor(ul_tbf); gprs_rlcmac_tbf_ul_fsm_destructor(ul_tbf);
- gprs_rlcmac_tbf_destructor(ul_tbf_as_tbf(ul_tbf)); + gprs_rlcmac_tbf_destructor(tbf); talloc_free(ul_tbf); + /* Inform the MS that the TBF pointer has been freed: */ + gprs_rlcmac_entity_ul_tbf_freed(gre, ul_tbf); }
/* whether the UL TBF is in Contention Resolution state (false = already succeeded)*/