Commit 23025837 authored by Robert Schmidt's avatar Robert Schmidt

Free F1 UE data struct only on UE release

Before this commit, as visible in the handler of an F1 UE release, it
can happen that we forward the RRC Release message to a UE and start the
release timer, while also removing the F1 UE data (containing e.g., the
CU UE ID). This can lead to asserts, since there might still be
subsequent traffic for such UE during a short time, while the DU does
not have the secondary UE ID stored anymore.

This commit changes the logic. It introduces function
nr_mac_release_ue() that removes the UE at MAC and RLC, frees the F1 UE
data (if applicable), and sends the complete, after timing expiry. If
the UE is out of sync, this function is used to free the UE immediately.

This fixes #685 and #698.
parent 82597e7e
......@@ -2809,6 +2809,30 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b
return 0;
}
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)) {
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);
}
}
void nr_mac_update_timers(module_id_t module_id,
frame_t frame,
sub_frame_t slot)
......@@ -2823,8 +2847,7 @@ 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)) {
nr_rlc_remove_ue(UE->rnti);
mac_remove_nr_ue(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
UE--;
......@@ -2963,7 +2986,7 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing)
{
// trigger 60ms
sched_ctrl->release_timer = 60 << subcarrier_spacing;
sched_ctrl->release_timer = 100 << subcarrier_spacing;
}
bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti)
......
......@@ -443,6 +443,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_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);
void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl);
......
......@@ -466,27 +466,24 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
{
/* mark UE as to be deleted after PUSCH failure */
gNB_MAC_INST *mac = RC.nrmac[0];
pthread_mutex_lock(&mac->sched_lock);
NR_SCHED_LOCK(&mac->sched_lock);
NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->gNB_DU_ue_id);
if (UE == NULL) {
LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Release Command\n", cmd->gNB_DU_ue_id);
NR_SCHED_UNLOCK(&mac->sched_lock);
return;
}
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_rlc_remove_ue(cmd->gNB_DU_ue_id);
mac_remove_nr_ue(mac, cmd->gNB_DU_ue_id);
nr_mac_release_ue(mac, cmd->gNB_DU_ue_id);
} else {
/* UE is in sync: forward release message and mark to be deleted
* after UL failure */
nr_rlc_srb_recv_sdu(cmd->gNB_DU_ue_id, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length);
nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
}
pthread_mutex_unlock(&mac->sched_lock);
f1ap_ue_context_release_complete_t complete = {
.gNB_CU_ue_id = cmd->gNB_CU_ue_id,
.gNB_DU_ue_id = cmd->gNB_DU_ue_id,
};
mac->mac_rrc.ue_context_release_complete(&complete);
du_remove_f1_ue_data(cmd->gNB_DU_ue_id);
NR_SCHED_UNLOCK(&mac->sched_lock);
}
void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment