From a92ab368f223699225ba675c21e6c6b485c25ee6 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Thu, 25 Jul 2024 13:37:38 +0000 Subject: [PATCH] Decouple UEContextReleaseComplete message generation from MAC UE release The next commit implements the release of all UEs following the F1 Reset message. It uses nr_mac_release_ue(), which as of now, triggered a release complete message automatically, which we don't want in the case of F1 Reset. This commit refactors the code to split UE release at MAC/RLC and release complete message sending to allow to release UEs without sending the complete. Corresponding users are updated. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 1 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 46 +++++++++++-------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 1 + 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 200a21258e..495eb30eef 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2190,6 +2190,7 @@ void nr_schedule_RA(module_id_t module_idP, if (ra->contention_resolution_timer < 0) { LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti); nr_mac_release_ue(mac, ra->rnti); + nr_mac_trigger_release_complete(mac, ra->rnti); nr_clear_ra_proc(ra); continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4c67bfdf35..5728f6bb3f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3013,32 +3013,36 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b return 0; } +void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti) +{ + // the CU might not know such UE, e.g., because we never sent a message to + // it, so there might not be a corresponding entry for such UE in the look up + // table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE + // MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the + // newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f + if (!du_exists_f1_ue_data(rnti)) + return; + + // unlock the scheduler temporarily to prevent possible deadlocks with + // du_remove_f1_ue_data() (and also while sending the message to RRC) + NR_SCHED_UNLOCK(&mac->sched_lock); + f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); + f1ap_ue_context_release_complete_t complete = { + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = rnti, + }; + mac->mac_rrc.ue_context_release_complete(&complete); + + du_remove_f1_ue_data(rnti); + NR_SCHED_LOCK(&mac->sched_lock); +} + void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti) { NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); nr_rlc_remove_ue(rnti); mac_remove_nr_ue(mac, rnti); - - // the CU might not know such UE, e.g., because we never sent a message to - // it, so there might not be a corresponding entry for such UE in the look up - // table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE - // MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the - // newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f - if (du_exists_f1_ue_data(rnti)) { - // unlock the scheduler temporarily to prevent possible deadlocks with - // du_remove_f1_ue_data() (and also while sending the message to RRC) - NR_SCHED_UNLOCK(&mac->sched_lock); - f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); - f1ap_ue_context_release_complete_t complete = { - .gNB_CU_ue_id = ue_data.secondary_ue, - .gNB_DU_ue_id = rnti, - }; - mac->mac_rrc.ue_context_release_complete(&complete); - - du_remove_f1_ue_data(rnti); - NR_SCHED_LOCK(&mac->sched_lock); - } } void nr_mac_update_timers(module_id_t module_id, @@ -3055,6 +3059,8 @@ void nr_mac_update_timers(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; if (nr_mac_check_release(sched_ctrl, UE->rnti)) { + // trigger release first as nr_mac_release_ue() invalidates UE ptr + nr_mac_trigger_release_complete(mac, UE->rnti); nr_mac_release_ue(mac, UE->rnti); // go back to examine the next UE, which is at the position the // current UE was diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 84f06c873c..938d5cf27b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -438,6 +438,7 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); +void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti); void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti); void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 9596260163..d47392491b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -627,6 +627,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ nr_mac_release_ue(mac, cmd->gNB_DU_ue_id); + nr_mac_trigger_release_complete(mac, cmd->gNB_DU_ue_id); } else { /* UE is in sync: forward release message and mark to be deleted * after UL failure */