From 2335f5b6cf0f6d2921a642cc413e718c372c51a7 Mon Sep 17 00:00:00 2001 From: andrewse Date: Mon, 30 Sep 2024 20:37:03 +0200 Subject: [PATCH 1/3] Don't call mac_rlc_data_ind when SRB0 already exist for UE. It can happen that L1 gives us a TB that we interpret as receiving UL MAC TB with LCID "UL_SCH_LCID_CCCH1". This might or might not be correct, but currently, we observe segfaults when trying to encode the cellgroup in send_initial_ul_rrc_message() (encode_cellGroupConfig()). This fix prevents a segfault by not delivering a MAC SDU to RLC if CCCH is already present. Note that in some cases, this could still happen, e.g. Resume Request. However, we don't support this message, so ignore it for the moment. This fix enables a gNB to operate continuously for extended periods (days), which is essential for real deployment scenarios. Closes: #756 --- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 11 +++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 27 ++++++++++--------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 21 +++++++-------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 2 +- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 5bc2a97fd7..bf754a7276 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3177,9 +3177,14 @@ void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_le mac->mac_rrc.initial_ul_rrc_message_transfer(0, &ul_rrc_msg); } -void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) +bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) { NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); + + /* activate SRB0 */ + if (!nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message)) + return false; + /* create this UE's initial CellGroup */ int CC_id = 0; int srb_id = 1; @@ -3189,9 +3194,6 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) UE->CellGroup = cellGroupConfig; - /* activate SRB0 */ - nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message); - /* the cellGroup sent to CU specifies there is SRB1, so create it */ DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1); const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0]; @@ -3201,6 +3203,7 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) int priority = bearer->mac_LogicalChannelConfig->ul_SpecificParameters->priority; nr_lc_config_t c = {.lcid = bearer->logicalChannelIdentity, .priority = priority}; nr_mac_add_lcid(&UE->UE_sched_ctrl, &c); + return true; } void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index d091d486ff..0bc9177eba 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -446,18 +446,19 @@ static int nr_process_mac_pdu(instance_t module_idP, LOG_D(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti); - prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE); - mac_rlc_data_ind(module_idP, - UE->rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - 0, - (char *) (pduP + mac_subheader_len), - mac_len, - 1, - NULL); + if (prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE)) { + mac_rlc_data_ind(module_idP, + UE->rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + 0, + (char *) (pduP + mac_subheader_len), + mac_len, + 1, + NULL); + } break; case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28): @@ -498,7 +499,7 @@ static int nr_process_mac_pdu(instance_t module_idP, break; default: - LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); + LOG_E(NR_MAC, "RNTI %0x, received unknown MAC header (LCID = 0x%02x)\n", UE->rnti, rx_lcid); return -1; break; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 9011e13f75..66e50e8607 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -436,7 +436,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset long get_lcid_from_drbid(int drb_id); long get_lcid_from_srbid(int srb_id); -void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE); +bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE); void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data); void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 46e0da26cf..b8fd148876 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -983,10 +983,17 @@ void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data); } -void nr_rlc_activate_srb0(int ue_id, +bool nr_rlc_activate_srb0(int ue_id, void *data, void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data)) { + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + if (ue->srb0 != NULL) { + LOG_W(RLC, "SRB0 already exists for UE %x, do nothing\n", ue_id); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return false; + } struct srb0_data *srb0_data = calloc(1, sizeof(struct srb0_data)); AssertFatal(srb0_data, "out of memory\n"); @@ -994,21 +1001,13 @@ void nr_rlc_activate_srb0(int ue_id, srb0_data->data = data; srb0_data->send_initial_ul_rrc_message = send_initial_ul_rrc_message; - nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); - if (ue->srb0 != NULL) { - LOG_W(RLC, "SRB0 already exists for UE %d, do nothing\n", ue_id); - free(srb0_data); - nr_rlc_manager_unlock(nr_rlc_ue_manager); - return; - } - nr_rlc_entity_t *nr_rlc_tm = new_nr_rlc_entity_tm(10000, - deliver_sdu_srb0, srb0_data); + deliver_sdu_srb0, srb0_data); nr_rlc_ue_add_srb_rlc_entity(ue, 0, nr_rlc_tm); LOG_I(RLC, "Activated srb0 for UE %d\n", ue_id); nr_rlc_manager_unlock(nr_rlc_ue_manager); + return true; } rlc_op_status_t rrc_rlc_config_req(const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index ea47b00f03..736c42a0b7 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -62,7 +62,7 @@ void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t cha void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size); -void nr_rlc_activate_srb0(int ue_id, +bool nr_rlc_activate_srb0(int ue_id, void *data, void (*send_initial_ul_rrc_message)(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data)); From ba10db149ad8106ba9cc05c0d7ecd55809960e27 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 2 Oct 2024 08:08:30 +0200 Subject: [PATCH 2/3] Logs when UE cannot use CCCH --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 0bc9177eba..21eefca9c5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -444,7 +444,7 @@ static int nr_process_mac_pdu(instance_t module_idP, mac_len = 6; } - LOG_D(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti); + LOG_I(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti); if (prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE)) { mac_rlc_data_ind(module_idP, @@ -458,6 +458,8 @@ static int nr_process_mac_pdu(instance_t module_idP, mac_len, 1, NULL); + } else { + LOG_E(NR_MAC, "prepare_initial_ul_rrc_message() returned false, cannot forward CCCH message\n"); } break; From 27d073d4f681ffae96ff49dce190ea7eb714d663 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 2 Oct 2024 10:32:26 +0200 Subject: [PATCH 3/3] Free CellGroup --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index bf754a7276..9cbb8877f5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3191,7 +3191,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; const NR_ServingCellConfig_t *sccd = mac->common_channels[CC_id].pre_ServingCellConfig; NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config); - + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; /* the cellGroup sent to CU specifies there is SRB1, so create it */