From d06e29bc9d8effbcdb2d3be424a6b7a1f323cb33 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 3 May 2023 12:23:54 +0200 Subject: [PATCH] sm: Avoid freeing the SME object too quickly At that point in time we may still need it, for instance to send the primitive to the upper layers. Still, we want it to be t the correct state when that happens. Hence, delay freeing the object to happen in next loop iteration, so that it is still available to submit the primitive, and even skip freeing the object if the SM SAP user decides to re-activate the PDP context in a synchronous code path from the primitive callback. Change-Id: I28655fc6286c92403e3e461cb6433b8567e20fd1 --- src/sm/sm_ms_fsm.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sm/sm_ms_fsm.c b/src/sm/sm_ms_fsm.c index 14f5ee7..2ce6f8d 100644 --- a/src/sm/sm_ms_fsm.c +++ b/src/sm/sm_ms_fsm.c @@ -30,6 +30,8 @@ #define X(s) (1 << (s)) +#define TIMER_DELAY_FREE 0 + static const struct osmo_tdef_state_timeout sm_ms_fsm_timeouts[32] = { [GPRS_SM_MS_ST_PDP_INACTIVE] = {}, [GPRS_SM_MS_ST_PDP_ACTIVE_PENDING] = { .T = 3380 }, @@ -43,9 +45,13 @@ static const struct osmo_tdef_state_timeout sm_ms_fsm_timeouts[32] = { static void st_sm_ms_pdp_inactive_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { - /* PDP became inactive, there's no use in keeping it */ - struct gprs_sm_ms_fsm_ctx *ctx = (struct gprs_sm_ms_fsm_ctx *)fi->priv; - gprs_sm_entity_free(ctx->sme); + /* PDP became inactive, there's no use in keeping it. + * Schedule asynchronous release of PDP. It will automatically be + * aborted as a consequence of changing state if user decides to + * automatically activate the PDP ctx in this same code path as an + * answer to a primitive submitted to it. */ + fi->T = TIMER_DELAY_FREE; + osmo_timer_schedule(&fi->timer, 0, 0); } static void st_sm_ms_pdp_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -149,6 +155,9 @@ static int sm_ms_fsm_timer_cb(struct osmo_fsm_inst *fi) struct gprs_sm_ms_fsm_ctx *ctx = (struct gprs_sm_ms_fsm_ctx *)fi->priv; switch (fi->T) { + case TIMER_DELAY_FREE: + gprs_sm_entity_free(ctx->sme); + break; case 3380: ctx->act_pdp_ctx_attempts++; LOGPFSML(ctx->fi, LOGL_INFO, "T3380 timeout attempts=%u\n", ctx->act_pdp_ctx_attempts);