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:
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user