From 67e53e72abafff9a122bf6e90aa728d0b6132a90 Mon Sep 17 00:00:00 2001 From: Cedric Roux <cedric.roux@eurecom.fr> Date: Mon, 16 Jan 2017 17:07:47 +0100 Subject: [PATCH] fix the use of get_eNB_UE_stats The function may return NULL if the UE has been dropped in the PHY layer but is still present in the MAC layer. Deal with the NULL case everywhere it's needed. --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 23 ++++++++++------- openair2/LAYER2/MAC/pre_processor.c | 30 ++++++++++++++++++++--- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 831b00a2f95..ec43c2434b5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -751,6 +751,20 @@ void schedule_ulsch_rnti(module_id_t module_idP, continue; } + /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ + /* TODO: refine? */ + drop_ue = 0; + for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); + drop_ue = 1; + break; + } + } + if (drop_ue == 1) + continue; + // loop over all active UL CC_ids for this UE for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list @@ -758,15 +772,6 @@ void schedule_ulsch_rnti(module_id_t module_idP, frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); - if (eNB_UE_stats==NULL) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - drop_ue=1; - continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); - } - - if (drop_ue==1) - continue; - if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) { LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); continue; // break; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index ed12d322c10..150f2c15de3 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -153,12 +153,25 @@ void assign_rbs_required (module_id_t Mod_id, UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; // UE_TEMPLATE *UE_template; LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; + int skip_ue; // clear rb allocations across all CC_ids for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { pCCid = UE_PCCID(Mod_id,UE_id); rnti = UE_list->UE_template[pCCid][UE_id].rnti; + /* skip UE not present in PHY (for any of its active CCs) */ + skip_ue = 0; + for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) { + CC_id = UE_list->ordered_CCids[n][UE_id]; + if (mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti) == NULL) { + skip_ue = 1; + break; + } + } + if (skip_ue == 1) + continue; + //update CQI information across component carriers for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) { @@ -262,7 +275,7 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin } // This function scans all CC_ids for a particular UE to find the maximum DL CQI - +// it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL) int maxcqi(module_id_t Mod_id,int32_t UE_id) { @@ -276,8 +289,9 @@ int maxcqi(module_id_t Mod_id,int32_t UE_id) eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,UE_RNTI(Mod_id,UE_id)); if (eNB_UE_stats==NULL) { - mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n"); - return 0; // not reached + /* the UE may have been removed in the PHY layer, don't exit */ + //mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n"); + return -1; } if (eNB_UE_stats->DL_cqi[0] > CQI) { @@ -329,7 +343,13 @@ void sort_UEs (module_id_t Mod_idP, round2 = maxround(Mod_idP,rnti2,frameP,subframeP,0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0); pCC_id2 = UE_PCCID(Mod_idP,UE_id2); - if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order + /* if 2nd UE is not in PHY, do nothing */ + if (cqi2 == -1) + continue; + /* if 1st UE is not in PHY, swap with 2nd UE */ + if (cqi1 == -1) { + swap_UEs(UE_list,UE_id1,UE_id2,0); + } else if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order swap_UEs(UE_list,UE_id1,UE_id2,0); } else if (round2 == round1) { // RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service. @@ -758,6 +778,8 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, int sf05_upper=-1,sf05_lower=-1; #endif LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); + if (eNB_UE_stats == NULL) return; + // initialize harq_pid and round mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti, frameP,subframeP, -- GitLab