Merge remote-tracking branch 'origin/fix_nr_reestablishment' into integration_2025_w24 (!3457)

Fix NR reestablishment by implementing the "DRB-suspend" at the MAC.
This means that the during reestablishment, gNB MAC discards received
DRB packets, and does not schedule DRB. Fix a couple of additional
issues in reestablishment.  # Please enter a commit message to explain
why this merge is necessary,

For additional information, see
https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/2668#note_119369
This commit is contained in:
Robert Schmidt
2025-06-13 10:25:57 +02:00
6 changed files with 65 additions and 35 deletions
@@ -335,6 +335,9 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, slot_t s
const int lcid = c->lcid;
const uint16_t rnti = UE->rnti;
LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid);
memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid]));
if (c->suspended)
continue;
if (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt))
continue;
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
@@ -399,8 +402,7 @@ static bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *U
// used if CORESET 0 is configured for the cell and the size of initial DL bandwidth part shall be used if CORESET 0 is not
// configured for the cell.
if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 && sched_ctrl->search_space->searchSpaceType
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common
&& dl_bwp->pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) {
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) {
if (sched_ctrl->coreset->controlResourceSetId == 0) {
bwp_info.bwpStart = nr_mac->cset0_bwp_start;
} else {
@@ -1183,8 +1185,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
// 3GPP TS 38.214 Section 5.1.2.2.2 Downlink resource allocation type 1
uint16_t riv_bwp_size = pdsch_pdu->BWPSize;
if (current_BWP->dci_format == NR_DL_DCI_FORMAT_1_0
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common
&& pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) {
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) {
if (gNB_mac->cset0_bwp_size > 0) {
riv_bwp_size = gNB_mac->cset0_bwp_size;
} else {
@@ -2104,6 +2104,7 @@ NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP)
void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia)
{
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->reconfigSpCellConfig);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability);
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
seq_arr_free(&sched_ctrl->lc_config, NULL);
@@ -3477,6 +3478,16 @@ static int cmp_lc_config(const void *va, const void *vb)
return 1;
}
nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid)
{
nr_lc_config_t c = {.lcid = lcid};
elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config);
if (elm.found)
return elm.it;
else
return NULL;
}
bool nr_mac_add_lcid(NR_UE_sched_ctrl_t* sched_ctrl, const nr_lc_config_t *c)
{
elm_arr_t elm = find_if(&sched_ctrl->lc_config, (void *) c, eq_lcid_config);
@@ -78,8 +78,7 @@ static bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE)
// case when DCI format 0_0 is decoded in any common search space in which case the size of the initial UL bandwidth part shall
// be used.
if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 && sched_ctrl->search_space->searchSpaceType
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common
&& ul_bwp->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) {
bwp_info.bwpSize = min(ul_bwp->BWPSize, UE->sc_info.initial_ul_BWPSize);
} else {
bwp_info.bwpSize = ul_bwp->BWPSize;
@@ -391,10 +390,15 @@ static int nr_process_mac_pdu(instance_t module_idP,
slot,
lcid);
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len);
const nr_lc_config_t *srbc = nr_mac_get_lc_config(sched_ctrl, lcid);
if (!srbc || srbc->suspended) {
LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len);
} else {
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len);
UE->mac_stats.ul.total_sdu_bytes += mac_len;
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
UE->mac_stats.ul.total_sdu_bytes += mac_len;
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
}
break;
case UL_SCH_LCID_DTCH ...(UL_SCH_LCID_DTCH + 28):
@@ -407,16 +411,21 @@ static int nr_process_mac_pdu(instance_t module_idP,
lcid,
module_idP,
mac_len);
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
const nr_lc_config_t *c = nr_mac_get_lc_config(sched_ctrl, lcid);
if (!c || c->suspended) {
LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len);
} else {
UE->mac_stats.ul.lc_bytes[lcid] += mac_len;
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len);
nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len);
sdus += 1;
/* Updated estimated buffer when receiving data */
if (sched_ctrl->estimated_ul_buffer >= mac_len)
sched_ctrl->estimated_ul_buffer -= mac_len;
else
sched_ctrl->estimated_ul_buffer = 0;
sdus += 1;
/* Updated estimated buffer when receiving data */
if (sched_ctrl->estimated_ul_buffer >= mac_len)
sched_ctrl->estimated_ul_buffer -= mac_len;
else
sched_ctrl->estimated_ul_buffer = 0;
}
break;
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
+1
View File
@@ -453,6 +453,7 @@ void process_addmod_bearers_cellGroupConfig(NR_UE_sched_ctrl_t *sched_ctrl,
const struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod);
bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c);
nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid);
bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid);
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, rnti_t *rnti);
+21 -16
View File
@@ -782,9 +782,20 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
"RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n");
} else if (req->ReconfigComplOutcome == RRCreconf_success) {
LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n");
if (UE->reconfigSpCellConfig) {
// in case of reestablishment, the spCellConfig had to be released
// temporarily. Reapply now before doing the reconfiguration.
UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig;
UE->reconfigSpCellConfig = NULL;
}
// we re-configure the BWP to apply the CellGroup and to use UE specific Search Space with DCIX1
nr_mac_clean_cellgroup(UE->CellGroup);
configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_ue_Specific, -1, -1);
for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) {
nr_lc_config_t *c = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i);
c->suspended = false;
nr_rlc_reestablish_entity(req->gNB_DU_ue_id, c->lcid);
}
}
if (ue_cap != NULL) {
@@ -949,15 +960,9 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
DevAssert(success);
}
if (UE->reestablish_rlc && dl_rrc->srb_id == 1) {
// we expected a reconfiguration to re-establish RLC, and this is on DCCH. We assume this is the reconfiguration.
for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) {
nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i);
nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, lc_config->lcid);
}
UE->reestablish_rlc = false;
}
/* if we get the old-gNB-DU-UE-ID, this means there is a reestablishment
* ongoing. */
if (dl_rrc->old_gNB_DU_ue_id != NULL) {
AssertFatal(*dl_rrc->old_gNB_DU_ue_id != dl_rrc->gNB_DU_ue_id,
"logic bug: current and old gNB DU UE ID cannot be the same\n");
@@ -968,30 +973,30 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
NR_UE_info_t *oldUE = find_nr_UE(&mac->UE_info, *dl_rrc->old_gNB_DU_ue_id);
AssertFatal(oldUE, "CU claims we should know UE %04x, but we don't\n", *dl_rrc->old_gNB_DU_ue_id);
pthread_mutex_lock(&mac->sched_lock);
/* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it
* from the current configuration. Also, expect the reconfiguration from
* the CU, so save the old UE's CellGroup for the new UE */
UE->CellGroup->spCellConfig = NULL;
uid_t temp_uid = UE->uid;
UE->uid = oldUE->uid;
oldUE->uid = temp_uid;
for (int i = 1; i < seq_arr_size(&oldUE->UE_sched_ctrl.lc_config); ++i) {
const nr_lc_config_t *c = seq_arr_at(&oldUE->UE_sched_ctrl.lc_config, i);
nr_mac_add_lcid(&UE->UE_sched_ctrl, c);
nr_lc_config_t new = *c;
new.suspended = true;
nr_mac_add_lcid(&UE->UE_sched_ctrl, &new);
}
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
UE->CellGroup = oldUE->CellGroup;
oldUE->CellGroup = NULL;
UE->mac_stats = oldUE->mac_stats;
/* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it
* from the current configuration. It will be reapplied when the
* reconfiguration has succeeded (indicated by the CU) */
UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig;
UE->CellGroup->spCellConfig = NULL;
mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id);
pthread_mutex_unlock(&mac->sched_lock);
nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id);
nr_rlc_update_id(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
/* 38.331 clause 5.3.7.4: apply the specified configuration defined in 9.2.1 for SRB1 */
nr_rlc_reconfigure_entity(dl_rrc->gNB_DU_ue_id, 1, NULL);
/* Set flag to trigger RLC re-establishment
* for remaining RBs in next RRCReconfiguration */
UE->reestablish_rlc = true;
instance_t f1inst = get_f1_gtp_instance();
if (f1inst >= 0) // we actually use F1-U
gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
+5 -2
View File
@@ -561,6 +561,8 @@ typedef struct NR_QoS_config_s {
typedef struct nr_lc_config {
uint8_t lcid;
/// flag if corresponding RB is suspended
bool suspended;
/// priority as specified in 38.321
int priority;
/// associated NSSAI for DRB
@@ -737,8 +739,9 @@ typedef struct {
NR_mac_stats_t mac_stats;
/// currently active CellGroupConfig
NR_CellGroupConfig_t *CellGroup;
/// reestablishRLC has to be signaled in RRCreconfiguration
bool reestablish_rlc;
/// in case of reestablishment, old spCellConfig to apply after
/// reconfiguration
NR_SpCellConfig_t *reconfigSpCellConfig;
interrupt_followup_action_t interrupt_action;
NR_UE_NR_Capability_t *capability;
// UE selected beam index