From 8d9a8ab59a40cf4aa73bf464ddb2184d519bb530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= <niccolo.iardella@unifi.it> Date: Tue, 13 Mar 2018 15:22:14 +0100 Subject: [PATCH] Add UE sorting on LCID priority --- openair2/COMMON/platform_types.h | 3 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 104 ++++++++++++++++++---- openair2/LAYER2/MAC/eNB_scheduler_dlsch.h | 12 ++- openair2/LAYER2/MAC/mac_proto.h | 6 ++ openair2/LAYER2/MAC/pre_processor.c | 33 +++++-- 5 files changed, 132 insertions(+), 26 deletions(-) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 3f736e5b3c..a94d785bee 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -110,7 +110,8 @@ typedef enum { CR_HOL = 2, CR_LC = 3, CR_CQI = 4, - CR_NUM = 5 + CR_LCP = 5, + CR_NUM = 6 } sorting_criterion_t; //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 44083a4610..472c4e2a11 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -70,6 +70,7 @@ extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; extern int slice_isolation[MAX_NUM_SLICES]; +extern int slice_priority[MAX_NUM_SLICES]; //------------------------------------------------------------------------------ void @@ -534,23 +535,44 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in } // Check for new sorting policy - if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) { + if (slice_sorting_current[i] != slice_sorting[i]) { LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]); - slice_sorting_policy_current[i] = slice_sorting_policy[i]; + module_idP, i, frameP, subframeP, slice_sorting_current[i], slice_sorting[i]); + slice_sorting_current[i] = slice_sorting[i]; + } + + // Check for new slice isolation + if (slice_isolation_current[i] != slice_isolation[i]) { + if (slice_isolation[i] != 1 && slice_isolation[i] != 0) { + LOG_W(MAC, + "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid slice isolation setting (%d), revert to its previous value (%d)\n", + module_idP, i, frameP, subframeP, slice_isolation[i], slice_isolation_current[i]); + slice_isolation[i] = slice_isolation_current[i]; + } else { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, slice_isolation_current[i], slice_isolation[i]); + slice_isolation_current[i] = slice_isolation[i]; + } + } + + // Check for new slice priority + if (slice_priority_current[i] != slice_priority[i]) { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, slice_priority_current[i], slice_priority[i]); + slice_priority_current[i] = slice_priority[i]; } // Check for new accounting policy - if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) { - if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) { + if (slice_accounting_current[i] != slice_accounting[i]) { + if (slice_accounting[i] > 1 || slice_accounting[i] < 0) { LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", - module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]); - slice_accounting_policy[i] = slice_accounting_policy_current[i]; + module_idP, i, frameP, subframeP, slice_accounting[i], slice_accounting_current[i]); + slice_accounting[i] = slice_accounting_current[i]; } else { LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]); - slice_accounting_policy_current[i] = slice_accounting_policy[i]; + module_idP, i, frameP, subframeP, slice_accounting_current[i], slice_accounting[i]); + slice_accounting_current[i] = slice_accounting[i]; } } @@ -1570,6 +1592,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; + int slice_sorted_list[MAX_NUM_SLICES], slice_id; int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX]; int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES]; uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; @@ -1613,7 +1636,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub } } - // TODO: Sort slices by priority and use the sorted list in the code below (For now we assume 0 = max_priority) + slice_priority_sort(slice_sorted_list); // MULTIPLEXING // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code @@ -1623,8 +1646,9 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub min_rb_unit = get_min_rb_unit(Mod_id, CC_id); for (i = 0; i < n_active_slices; ++i) { + slice_id = slice_sorted_list[i]; - if (has_traffic[CC_id][i] == 0) continue; + if (has_traffic[CC_id][slice_id] == 0) continue; // Build an ad-hoc allocation mask fo the slice for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { @@ -1644,12 +1668,13 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub // Sort UE again // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) - sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP); + // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it + sort_UEs(Mod_id, (slice_id_t) slice_id, frameP, subframeP); - nb_rbs_remaining = pre_processor_results[i].nb_rbs_remaining; - nb_rbs_required = pre_processor_results[i].nb_rbs_required; - rballoc_sub = pre_processor_results[i].slice_allocated_rbgs; - MIMO_mode_indicator = pre_processor_results[i].MIMO_mode_indicator; + nb_rbs_remaining = pre_processor_results[slice_id].nb_rbs_remaining; + nb_rbs_required = pre_processor_results[slice_id].nb_rbs_required; + rballoc_sub = pre_processor_results[slice_id].slice_allocated_rbgs; + MIMO_mode_indicator = pre_processor_results[slice_id].MIMO_mode_indicator; // Allocation for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { @@ -1699,6 +1724,32 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub } } +//------------------------------------------------------------------------------ +void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + int UE_id, CC_id, i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; ++CC_id) { + for (i = 0; i < n_active_slices; ++i) { + + // Sort UE again + // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it + sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP); + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + // TODO: Do something here + ue_sched_ctl->pre_nb_available_rbs[CC_id]; + } + } + } +} + + //------------------------------------------------------------------------------ void fill_DLSCH_dci(module_id_t module_idP, @@ -2252,3 +2303,24 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) stop_meas(&eNB->schedule_pch); return; } + +static int slice_priority_compare(const void *_a, const void *_b) { + + int slice_id1 = *(const int *) _a; + int slice_id2 = *(const int *) _b; + + if (slice_priority[slice_id1] > slice_priority[slice_id2]) { + return -1; + } + return 1; +} + +void slice_priority_sort(int slice_list[MAX_NUM_SLICES]) { + + int i; + for (i = 0; i < MAX_NUM_SLICES; ++i) { + slice_list[i] = i; + } + + qsort(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare); +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 8bd227645c..321f83c20d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -48,7 +48,11 @@ float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_total = 0; float slice_percentage_total_current = 0; float slice_percentage_avg = 0.25; + int slice_isolation[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_isolation_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_priority[MAX_NUM_SLICES] = {10, 5, 2, 0}; +int slice_priority_current[MAX_NUM_SLICES] = {10, 5, 2, 0}; // Frequency ranges for slice positioning int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; @@ -59,12 +63,12 @@ int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; // The lists of criteria that enforce the sorting policies of the slices -uint32_t slice_sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; -uint32_t slice_sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +uint32_t slice_sorting[MAX_NUM_SLICES] = {0x012345, 0x012345, 0x012345, 0x012345}; +uint32_t slice_sorting_current[MAX_NUM_SLICES] = {0x012345, 0x012345, 0x012345, 0x012345}; // Accounting policy (just greedy(1) or fair(0) setting for now) -int slice_accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0}; -int slice_accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_accounting[MAX_NUM_SLICES] = {0, 0, 0, 0}; +int slice_accounting_current[MAX_NUM_SLICES] = {0, 0, 0, 0}; int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 56bf7a25d4..98b6c8fbe0 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -260,10 +260,16 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); +void slice_priority_sort(int slice_list[MAX_NUM_SLICES]); + void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP); +void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP); + void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int UE_id, uint8_t CC_id, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 73f9724c8a..48987d785e 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -57,8 +57,8 @@ extern RAN_CONTEXT_t RC; extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; extern int slice_position[MAX_NUM_SLICES*2]; -extern uint32_t slice_sorting_policy[MAX_NUM_SLICES]; -extern int slice_accounting_policy[MAX_NUM_SLICES]; +extern uint32_t slice_sorting[MAX_NUM_SLICES]; +extern int slice_accounting[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; @@ -315,6 +315,20 @@ int maxcqi(module_id_t Mod_id, int32_t UE_id) { return CQI; } +long min_lcgidpriority(module_id_t Mod_id, int32_t UE_id) { + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int i; + int pCC_id = UE_PCCID(Mod_id, UE_id); + long ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[0]; + + for (i = 1; i < 11; ++i) { + if (UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i] < ret) + ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i]; + } + + return ret; +} + struct sort_ue_dl_params { int Mod_idP; int frameP; @@ -343,6 +357,9 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi2 = maxcqi(params->Mod_idP, UE_id2); + long lcgid1 = min_lcgidpriority(params->Mod_idP, UE_id1); + long lcgid2 = min_lcgidpriority(params->Mod_idP, UE_id2); + for (i = 0; i < CR_NUM; ++i) { switch (UE_list->sorting_criteria[slice_id][i]) { @@ -390,6 +407,12 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) if (cqi1 < cqi2) return 1; + case CR_LCP : + if (lcgid1 < lcgid2) + return -1; + if (lcgid1 > lcgid2) + return 1; + default : break; } @@ -402,7 +425,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { int i; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - uint32_t policy = slice_sorting_policy[slice_id]; + uint32_t policy = slice_sorting[slice_id]; uint32_t mask = 0x0000000F; uint16_t criterion; @@ -410,7 +433,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); if (criterion >= CR_NUM) { LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - slice_sorting_policy[slice_id] = 0x1234; + slice_sorting[slice_id] = 0x1234; break; } UE_list->sorting_criteria[slice_id][i] = criterion; @@ -649,7 +672,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Reduces the available RBs according to slicing configuration dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); - switch (slice_accounting_policy[slice_id]) { + switch (slice_accounting[slice_id]) { // If greedy scheduling, try to account all the required RBs case 1: -- GitLab