Commit 58c2a006 authored by Robert Schmidt's avatar Robert Schmidt

MAC: slicing conf struct in RC

- introduce structure in RC for slicing conf (UL/DL)
- move global variables regarding slice configuration into RC
- change ue_slice_membership(): consider UL/DL
- remove the unnecessary header files
- set default parameters: one slice
parent 1e840a99
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
*/ */
#define _GNU_SOURCE
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_proto.h"
...@@ -44,7 +45,6 @@ ...@@ -44,7 +45,6 @@
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
//#include "LAYER2/MAC/pre_processor.c" //#include "LAYER2/MAC/pre_processor.c"
#include "eNB_scheduler_dlsch.h"
#include "pdcp.h" #include "pdcp.h"
#include "SIMULATION/TOOLS/sim.h" // for taus #include "SIMULATION/TOOLS/sim.h" // for taus
...@@ -62,11 +62,9 @@ ...@@ -62,11 +62,9 @@
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
//#define DEBUG_eNB_SCHEDULER 1 //#define DEBUG_eNB_SCHEDULER 1
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode; 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 void
...@@ -413,195 +411,196 @@ void ...@@ -413,195 +411,196 @@ void
schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) {
int i = 0; int i = 0;
slice_info_t *sli = &RC.mac[module_idP]->slice_info;
slice_percentage_total = 0; sli->tot_pct_dl = 0;
slice_percentage_avg = 1.0 / n_active_slices; sli->avg_pct_dl = 1.0 / sli->n_dl;
slice_counter = n_active_slices; sli->slice_counter = sli->n_dl;
// reset the slice percentage for inactive slices // reset the slice percentage for inactive slices
for (i = n_active_slices; i < MAX_NUM_SLICES; i++) { for (i = sli->n_dl; i < MAX_NUM_SLICES; i++) {
slice_percentage[i] = 0; sli->dl[i].pct = 0;
} }
for (i = 0; i < n_active_slices; i++) { for (i = 0; i < sli->n_dl; i++) {
if (slice_percentage[i] < 0) { if (sli->dl[i].pct < 0) {
LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero",
module_idP, frameP, subframeP, i, slice_percentage[i]); module_idP, frameP, subframeP, i, sli->dl[i].pct);
slice_percentage[i] = 0; sli->dl[i].pct = 0;
} }
slice_percentage_total += slice_percentage[i]; sli->tot_pct_dl += sli->dl[i].pct;
} }
// Check for *intra*slice share activation // Check for *intra*slice share activation
if (intraslice_share_active_current != intraslice_share_active) { if (sli->intraslice_share_active_current != sli->intraslice_share_active) {
if (intraslice_share_active != 1 && intraslice_share_active != 0) { if (sli->intraslice_share_active != 1 && sli->intraslice_share_active != 0) {
LOG_W(MAC, LOG_W(MAC,
"[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n", "[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n",
module_idP, frameP, subframeP, intraslice_share_active, intraslice_share_active_current); module_idP, frameP, subframeP, sli->intraslice_share_active, sli->intraslice_share_active_current);
intraslice_share_active = intraslice_share_active_current; sli->intraslice_share_active = sli->intraslice_share_active_current;
} else { } else {
LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n", LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n",
module_idP, frameP, subframeP, intraslice_share_active_current, intraslice_share_active); module_idP, frameP, subframeP, sli->intraslice_share_active_current, sli->intraslice_share_active);
intraslice_share_active_current = intraslice_share_active; sli->intraslice_share_active_current = sli->intraslice_share_active;
} }
} }
// Check for *inter*slice share activation // Check for *inter*slice share activation
if (interslice_share_active_current != interslice_share_active) { if (sli->interslice_share_active_current != sli->interslice_share_active) {
if (interslice_share_active != 1 && interslice_share_active != 0) { if (sli->interslice_share_active != 1 && sli->interslice_share_active != 0) {
LOG_W(MAC, LOG_W(MAC,
"[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n", "[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n",
module_idP, frameP, subframeP, interslice_share_active, interslice_share_active_current); module_idP, frameP, subframeP, sli->interslice_share_active, sli->interslice_share_active_current);
interslice_share_active = interslice_share_active_current; sli->interslice_share_active = sli->interslice_share_active_current;
} else { } else {
LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n", LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n",
module_idP, frameP, subframeP, interslice_share_active_current, interslice_share_active); module_idP, frameP, subframeP, sli->interslice_share_active_current, sli->interslice_share_active);
interslice_share_active_current = interslice_share_active; sli->interslice_share_active_current = sli->interslice_share_active;
} }
} }
for (i = 0; i < n_active_slices; i++) { for (i = 0; i < sli->n_dl; i++) {
// Load any updated functions // Load any updated functions
if (update_dl_scheduler[i] > 0) { if (sli->dl[i].update_sched > 0) {
slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); sli->dl[i].sched_cb = dlsym(NULL, sli->dl[i].sched_name);
update_dl_scheduler[i] = 0; sli->dl[i].update_sched = 0;
update_dl_scheduler_current[i] = 0; sli->dl[i].update_sched_current = 0;
LOG_I(MAC, "update dl scheduler slice %d\n", i); LOG_I(MAC, "update dl scheduler slice %d\n", i);
} }
if (slice_percentage_total <= 1.0) { // the new total RB share is within the range if (sli->tot_pct_dl <= 1.0) { // the new total RB share is within the range
// check if the number of slices has changed, and log // check if the number of slices has changed, and log
if (n_active_slices_current != n_active_slices) { if (sli->n_dl_current != sli->n_dl) {
if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { if ((sli->n_dl > 0) && (sli->n_dl <= MAX_NUM_SLICES)) {
LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n",
module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); module_idP, frameP, subframeP, sli->n_dl_current, sli->n_dl);
n_active_slices_current = n_active_slices; sli->n_dl_current = sli->n_dl;
} else { } else {
LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n", LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n",
n_active_slices, n_active_slices_current); sli->n_dl, sli->n_dl_current);
n_active_slices = n_active_slices_current; sli->n_dl = sli->n_dl_current;
} }
} }
// check if the slice rb share has changed, and log the console // check if the slice rb share has changed, and log the console
if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage if (sli->dl[i].pct_current != sli->dl[i].pct) { // new slice percentage
LOG_I(MAC, LOG_I(MAC,
"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n",
module_idP, i, frameP, subframeP, slice_percentage_total_current, slice_percentage_total, module_idP, i, frameP, subframeP, sli->tot_pct_dl_current, sli->tot_pct_dl,
slice_percentage_current[i], slice_percentage[i]); sli->dl[i].pct_current, sli->dl[i].pct);
slice_percentage_total_current = slice_percentage_total; sli->tot_pct_dl_current = sli->tot_pct_dl;
slice_percentage_current[i] = slice_percentage[i]; sli->dl[i].pct_current = sli->dl[i].pct;
} }
// check if the slice max MCS, and log the console // check if the slice max MCS, and log the console
if (slice_maxmcs_current[i] != slice_maxmcs[i]) { if (sli->dl[i].maxmcs_current != sli->dl[i].maxmcs) {
if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)) { if ((sli->dl[i].maxmcs >= 0) && (sli->dl[i].maxmcs < 29)) {
LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n",
module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); module_idP, i, frameP, subframeP, sli->dl[i].maxmcs_current, sli->dl[i].maxmcs);
slice_maxmcs_current[i] = slice_maxmcs[i]; sli->dl[i].maxmcs_current = sli->dl[i].maxmcs;
} else { } else {
LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n", LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",
module_idP, i, slice_maxmcs[i], slice_maxmcs_current[i]); module_idP, i, sli->dl[i].maxmcs, sli->dl[i].maxmcs_current);
slice_maxmcs[i] = slice_maxmcs_current[i]; sli->dl[i].maxmcs = sli->dl[i].maxmcs_current;
} }
} }
// check if a new scheduler, and log the console // check if a new scheduler, and log the console
if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ if (sli->dl[i].update_sched_current != sli->dl[i].update_sched) {
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
module_idP, i, frameP, subframeP, dl_scheduler_type[i]); module_idP, i, frameP, subframeP, sli->dl[i].sched_name);
update_dl_scheduler_current[i] = update_dl_scheduler[i]; sli->dl[i].update_sched_current = sli->dl[i].update_sched;
} }
} else { } else {
// here we can correct the values, e.g. reduce proportionally // here we can correct the values, e.g. reduce proportionally
if (n_active_slices == n_active_slices_current) { if (sli->n_dl == sli->n_dl_current) {
LOG_W(MAC, LOG_W(MAC,
"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
module_idP, i, slice_percentage_total_current, slice_percentage_total); module_idP, i, sli->tot_pct_dl_current, sli->tot_pct_dl);
if (slice_percentage[i] >= slice_percentage_avg) { if (sli->dl[i].pct >= sli->avg_pct_dl) {
slice_percentage[i] -= 0.1; sli->dl[i].pct -= 0.1;
slice_percentage_total -= 0.1; sli->tot_pct_dl -= 0.1;
} }
} else { } else {
LOG_W(MAC, LOG_W(MAC,
"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
module_idP, i, slice_percentage_total_current, slice_percentage_total, module_idP, i, sli->tot_pct_dl_current, sli->tot_pct_dl,
n_active_slices, n_active_slices_current); sli->n_dl, sli->n_dl_current);
n_active_slices = n_active_slices_current; sli->n_dl = sli->n_dl_current;
slice_percentage[i] = slice_percentage_current[i]; sli->dl[i].pct = sli->dl[i].pct_current;
} }
} }
// Check for new slice positions // Check for new slice positions
if (slice_position[i * 2] > slice_position[i * 2 + 1] || if (sli->dl[i].pos_low > sli->dl[i].pos_high ||
slice_position[i * 2] < 0 || sli->dl[i].pos_low < 0 ||
slice_position[i * 2 + 1] > N_RBG_MAX) { sli->dl[i].pos_high > N_RBG_MAX) {
LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n",
module_idP, i, module_idP, i,
slice_position[i * 2], slice_position[i * 2 + 1], sli->dl[i].pos_low, sli->dl[i].pos_high,
slice_position_current[i * 2], slice_position_current[i * 2 + 1]); sli->dl[i].pos_low_current, sli->dl[i].pos_high_current);
slice_position[i * 2] = slice_position_current[i * 2]; sli->dl[i].pos_low = sli->dl[i].pos_low_current;
slice_position[i * 2 + 1] = slice_position_current[i * 2 + 1]; sli->dl[i].pos_high = sli->dl[i].pos_high_current;
} else { } else {
if (slice_position_current[i * 2] != slice_position[i * 2]) { if (sli->dl[i].pos_low_current != sli->dl[i].pos_low) {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_position_current[i * 2], slice_position[i * 2]); module_idP, i, frameP, subframeP, sli->dl[i].pos_low_current, sli->dl[i].pos_low);
slice_position_current[i * 2] = slice_position[i * 2]; sli->dl[i].pos_low_current = sli->dl[i].pos_low;
} }
if (slice_position_current[i * 2 + 1] != slice_position[i * 2 + 1]) { if (sli->dl[i].pos_high_current != sli->dl[i].pos_high) {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_position_current[i * 2 + 1], slice_position[i * 2 + 1]); module_idP, i, frameP, subframeP, sli->dl[i].pos_high_current, sli->dl[i].pos_high);
slice_position_current[i * 2 + 1] = slice_position[i * 2 + 1]; sli->dl[i].pos_high_current = sli->dl[i].pos_high;
} }
} }
// Check for new sorting policy // Check for new sorting policy
if (slice_sorting_current[i] != slice_sorting[i]) { if (sli->dl[i].sorting_current != sli->dl[i].sorting) {
LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", 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_current[i], slice_sorting[i]); module_idP, i, frameP, subframeP, sli->dl[i].sorting_current, sli->dl[i].sorting);
slice_sorting_current[i] = slice_sorting[i]; sli->dl[i].sorting_current = sli->dl[i].sorting;
} }
// Check for new slice isolation // Check for new slice isolation
if (slice_isolation_current[i] != slice_isolation[i]) { if (sli->dl[i].isol_current != sli->dl[i].isol) {
if (slice_isolation[i] != 1 && slice_isolation[i] != 0) { if (sli->dl[i].isol != 1 && sli->dl[i].isol != 0) {
LOG_W(MAC, LOG_W(MAC,
"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid slice isolation setting (%d), revert to its previous value (%d)\n", "[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]); module_idP, i, frameP, subframeP, sli->dl[i].isol, sli->dl[i].isol_current);
slice_isolation[i] = slice_isolation_current[i]; sli->dl[i].isol = sli->dl[i].isol_current;
} else { } else {
LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n", 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]); module_idP, i, frameP, subframeP, sli->dl[i].isol_current, sli->dl[i].isol);
slice_isolation_current[i] = slice_isolation[i]; sli->dl[i].isol_current = sli->dl[i].isol;
} }
} }
// Check for new slice priority // Check for new slice priority
if (slice_priority_current[i] != slice_priority[i]) { if (sli->dl[i].prio_current != sli->dl[i].prio) {
LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%x-->%x)\n", LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice priority setting has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_priority_current[i], slice_priority[i]); module_idP, i, frameP, subframeP, sli->dl[i].prio_current, sli->dl[i].prio);
slice_priority_current[i] = slice_priority[i]; sli->dl[i].prio_current = sli->dl[i].prio;
} }
// Check for new accounting policy // Check for new accounting policy
if (slice_accounting_current[i] != slice_accounting[i]) { if (sli->dl[i].accounting_current != sli->dl[i].accounting) {
if (slice_accounting[i] > 1 || slice_accounting[i] < 0) { if (sli->dl[i].accounting > 1 || sli->dl[i].accounting < 0) {
LOG_W(MAC, LOG_W(MAC,
"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", "[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[i], slice_accounting_current[i]); module_idP, i, frameP, subframeP, sli->dl[i].accounting, sli->dl[i].accounting_current);
slice_accounting[i] = slice_accounting_current[i]; sli->dl[i].accounting = sli->dl[i].accounting_current;
} else { } else {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", 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_current[i], slice_accounting[i]); module_idP, i, frameP, subframeP, sli->dl[i].accounting_current, sli->dl[i].accounting);
slice_accounting_current[i] = slice_accounting[i]; sli->dl[i].accounting_current = sli->dl[i].accounting;
} }
} }
// Run each enabled slice-specific schedulers one by one // Run each enabled slice-specific schedulers one by one
slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/);
} }
} }
...@@ -728,15 +727,15 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, ...@@ -728,15 +727,15 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT);
slice_counter--; RC.mac[module_idP]->slice_info.slice_counter--;
// Do the multiplexing and actual allocation only when all slices have been pre-processed. // Do the multiplexing and actual allocation only when all slices have been pre-processed.
if (slice_counter > 0) { if (RC.mac[module_idP]->slice_info.slice_counter > 0) {
stop_meas(&eNB->schedule_dlsch); stop_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
return; return;
} }
if (interslice_share_active) { if (RC.mac[module_idP]->slice_info.interslice_share_active) {
dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP); dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP);
} }
...@@ -764,7 +763,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, ...@@ -764,7 +763,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
continue_flag = 1; continue_flag = 1;
} }
if (!ue_slice_membership(UE_id, slice_idP)) if (!ue_slice_membership(UE_id, slice_idP, RC.mac[module_idP]->slice_info.n_dl))
continue; continue;
if (continue_flag != 1) { if (continue_flag != 1) {
...@@ -839,7 +838,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, ...@@ -839,7 +838,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
} else { // this operation is also done in the preprocessor } else { // this operation is also done in the preprocessor
eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,
slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); RC.mac[module_idP]->slice_info.dl[slice_idP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
} }
// Store stats // Store stats
...@@ -1614,6 +1613,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1614,6 +1613,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
int owned, used; int owned, used;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
COMMON_channels_t *cc; COMMON_channels_t *cc;
int N_RBG[NFAPI_CC_MAX]; int N_RBG[NFAPI_CC_MAX];
...@@ -1637,10 +1637,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1637,10 +1637,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
cc = &RC.mac[Mod_id]->common_channels[CC_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id];
N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
for (i = 0; i < n_active_slices; ++i) { for (i = 0; i < sli->n_dl; ++i) {
owned = pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg];
if (owned) { if (owned) {
used = pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg]; used = sli->pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg];
free_rbgs_map[CC_id][rbg] = used ? -1 : i; free_rbgs_map[CC_id][rbg] = used ? -1 : i;
break; break;
} }
...@@ -1651,10 +1651,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1651,10 +1651,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
// Find out which slices need other resources. // Find out which slices need other resources.
// FIXME: I don't think is really needed since we check nb_rbs_remaining later // FIXME: I don't think is really needed since we check nb_rbs_remaining later
for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) {
for (i = 0; i < n_active_slices; ++i) { for (i = 0; i < sli->n_dl; ++i) {
has_traffic[CC_id][i] = 0; has_traffic[CC_id][i] = 0;
for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) {
if (pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { if (sli->pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) {
has_traffic[CC_id][i] = 1; has_traffic[CC_id][i] = 1;
break; break;
} }
...@@ -1662,7 +1662,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1662,7 +1662,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
} }
} }
slice_priority_sort(slice_sorted_list); slice_priority_sort(Mod_id, slice_sorted_list);
// MULTIPLEXING // MULTIPLEXING
// This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code
...@@ -1671,7 +1671,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1671,7 +1671,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
min_rb_unit = get_min_rb_unit(Mod_id, CC_id); min_rb_unit = get_min_rb_unit(Mod_id, CC_id);
for (i = 0; i < n_active_slices; ++i) { for (i = 0; i < sli->n_dl; ++i) {
slice_id = slice_sorted_list[i]; slice_id = slice_sorted_list[i];
if (has_traffic[CC_id][slice_id] == 0) continue; if (has_traffic[CC_id][slice_id] == 0) continue;
...@@ -1683,7 +1683,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1683,7 +1683,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
allocation_mask[CC_id][rbg] = 0; allocation_mask[CC_id][rbg] = 0;
continue; continue;
} }
if (slice_isolation[free_rbgs_map[CC_id][rbg]] == 1) { if (sli->dl[free_rbgs_map[CC_id][rbg]].isol == 1) {
// RBG belongs to an isolated slice // RBG belongs to an isolated slice
allocation_mask[CC_id][rbg] = 0; allocation_mask[CC_id][rbg] = 0;
continue; continue;
...@@ -1697,10 +1697,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub ...@@ -1697,10 +1697,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub
// FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it // 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); sort_UEs(Mod_id, (slice_id_t) slice_id, frameP, subframeP);
nb_rbs_remaining = pre_processor_results[slice_id].nb_rbs_remaining; nb_rbs_remaining = sli->pre_processor_results[slice_id].nb_rbs_remaining;
nb_rbs_required = pre_processor_results[slice_id].nb_rbs_required; nb_rbs_required = sli->pre_processor_results[slice_id].nb_rbs_required;
rballoc_sub = pre_processor_results[slice_id].slice_allocated_rbgs; rballoc_sub = sli->pre_processor_results[slice_id].slice_allocated_rbgs;
MIMO_mode_indicator = pre_processor_results[slice_id].MIMO_mode_indicator; MIMO_mode_indicator = sli->pre_processor_results[slice_id].MIMO_mode_indicator;
// Allocation // Allocation
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
...@@ -1756,10 +1756,11 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ ...@@ -1756,10 +1756,11 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_
{ {
int UE_id, CC_id, i; int UE_id, CC_id, i;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) {
for (i = 0; i < n_active_slices; ++i) { for (i = 0; i < sli->n_dl; ++i) {
// Sort UE again // Sort UE again
// FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it
...@@ -2330,23 +2331,25 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) ...@@ -2330,23 +2331,25 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
return; return;
} }
static int slice_priority_compare(const void *_a, const void *_b) { static int slice_priority_compare(const void *_a, const void *_b, void *_c)
{
int slice_id1 = *(const int *) _a; const int slice_id1 = *(const int *) _a;
int slice_id2 = *(const int *) _b; const int slice_id2 = *(const int *) _b;
const module_id_t Mod_id = *(int *) _c;
const slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
if (slice_priority[slice_id1] > slice_priority[slice_id2]) { if (sli->dl[slice_id1].prio > sli->dl[slice_id2].prio) {
return -1; return -1;
} }
return 1; return 1;
} }
void slice_priority_sort(int slice_list[MAX_NUM_SLICES]) { void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES])
{
int i; int i;
for (i = 0; i < MAX_NUM_SLICES; ++i) { for (i = 0; i < MAX_NUM_SLICES; ++i) {
slice_list[i] = i; slice_list[i] = i;
} }
qsort(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare); qsort_r(slice_list, MAX_NUM_SLICES, sizeof(int), slice_priority_compare, &Mod_id);
} }
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file LAYER2/MAC/eNB_scheduler_dlsch.h
* \brief DLSCH Scheduler policy variables used during different phases of scheduling
* \author Navid Nikaein and Niccolo' Iardella
* \date 2018
* \version 0.2
* \email navid.nikaein@eurecom.fr
*/
/** @defgroup _oai2 openair2 Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
/*@}*/
#ifndef __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__
#define __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__
// number of active slices for past and current time
int n_active_slices = 1;
int n_active_slices_current = 1;
int slice_counter = 0;
int intraslice_share_active = 1;
int intraslice_share_active_current = 1;
int interslice_share_active = 1;
int interslice_share_active_current = 1;
// RB share for each slice for past and current time
float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
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};
int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX};
// MAX MCS for each slice for past and current time
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[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[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 };
// name of available scheduler
char *dl_scheduler_type[MAX_NUM_SLICES] =
{ "schedule_ue_spec",
"schedule_ue_spec",
"schedule_ue_spec",
"schedule_ue_spec"
};
// pointer to the slice specific scheduler
slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0};
pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
#endif //__LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__
...@@ -62,8 +62,6 @@ extern uint16_t frame_cnt; ...@@ -62,8 +62,6 @@ extern uint16_t frame_cnt;
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern int n_active_slices;
int choose(int n, int k) int choose(int n, int k)
{ {
int res = 1; int res = 1;
...@@ -4541,7 +4539,7 @@ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) ...@@ -4541,7 +4539,7 @@ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs)
return (uint16_t) floor(rb_percentage * total_rbs); return (uint16_t) floor(rb_percentage * total_rbs);
} }
int ue_slice_membership(int UE_id, int slice_id) int ue_slice_membership(int UE_id, int slice_id, int n_active_slices)
{ {
if ((slice_id < 0) || (slice_id > n_active_slices)) if ((slice_id < 0) || (slice_id > n_active_slices))
LOG_W(MAC, "out of range slice id %d\n", slice_id); LOG_W(MAC, "out of range slice id %d\n", slice_id);
......
...@@ -48,7 +48,6 @@ ...@@ -48,7 +48,6 @@
#include "assertions.h" #include "assertions.h"
//#include "LAYER2/MAC/pre_processor.c" //#include "LAYER2/MAC/pre_processor.c"
#include "eNB_scheduler_ulsch.h"
#include "pdcp.h" #include "pdcp.h"
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
...@@ -64,6 +63,9 @@ ...@@ -64,6 +63,9 @@
#include "T.h" #include "T.h"
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1 #define DEBUG_eNB_SCHEDULER 1
...@@ -923,6 +925,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, ...@@ -923,6 +925,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
uint16_t first_rb[NFAPI_CC_MAX], i; uint16_t first_rb[NFAPI_CC_MAX], i;
int CC_id; int CC_id;
eNB_MAC_INST *mac = RC.mac[module_idP]; eNB_MAC_INST *mac = RC.mac[module_idP];
slice_info_t *sli = &RC.mac[module_idP]->slice_info;
COMMON_channels_t *cc; COMMON_channels_t *cc;
start_meas(&mac->schedule_ulsch); start_meas(&mac->schedule_ulsch);
...@@ -1037,112 +1040,112 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, ...@@ -1037,112 +1040,112 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
// perform slice-specifc operations // perform slice-specifc operations
total_slice_percentage_uplink=0; sli->tot_pct_ul = 0;
avg_slice_percentage_uplink=1.0/n_active_slices_uplink; sli->avg_pct_ul = 1.0 / sli->n_ul;
// reset the slice percentage for inactive slices // reset the slice percentage for inactive slices
for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { for (i = sli->n_ul; i< MAX_NUM_SLICES; i++) {
slice_percentage_uplink[i]=0; sli->ul[i].pct = 0;
} }
for (i = 0; i < n_active_slices_uplink; i++) { for (i = 0; i < sli->n_ul; i++) {
if (slice_percentage_uplink[i] < 0 ){ if (sli->ul[i].pct < 0 ){
LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero",
module_idP, frameP, subframeP, i, slice_percentage_uplink[i]); module_idP, frameP, subframeP, i, sli->ul[i].pct);
slice_percentage_uplink[i]=0; sli->ul[i].pct = 0;
} }
total_slice_percentage_uplink+=slice_percentage_uplink[i]; sli->tot_pct_ul += sli->ul[i].pct;
} }
for (i = 0; i < n_active_slices_uplink; i++) { for (i = 0; i < sli->n_ul; i++) {
// Load any updated functions // Load any updated functions
if (update_ul_scheduler[i] > 0 ) { if (sli->ul[i].update_sched > 0 ) {
slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); sli->ul[i].sched_cb = dlsym(NULL, sli->ul[i].sched_name);
update_ul_scheduler[i] = 0; sli->ul[i].update_sched = 0;
update_ul_scheduler_current[i] = 0; sli->ul[i].update_sched_current = 0;
//slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; //sli->ul[i].pct_current = sli->ul[i].pct;
//total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; //sli->tot_pct_ul_current += sli->ul[i].pct;
//if (total_slice_percentage_current_uplink> 1) //if (sli->tot_pct_ul_current > 1)
//total_slice_percentage_current_uplink=1; //sli->tot_pct_ul_current = 1;
LOG_I(MAC,"update ul scheduler slice %d\n", i); LOG_I(MAC,"update ul scheduler slice %d\n", i);
} }
// the new total RB share is within the range // the new total RB share is within the range
if (total_slice_percentage_uplink <= 1.0){ if (sli->tot_pct_ul <= 1.0){
// check if the number of slices has changed, and log // check if the number of slices has changed, and log
if (n_active_slices_current_uplink != n_active_slices_uplink ){ if (sli->n_ul_current != sli->n_ul ){
if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { if ((sli->n_ul > 0) && (sli->n_ul <= MAX_NUM_SLICES)) {
LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n",
module_idP, frameP, subframeP, n_active_slices_current_uplink, n_active_slices_uplink); module_idP, frameP, subframeP, sli->n_ul_current, sli->n_ul);
n_active_slices_current_uplink = n_active_slices_uplink; sli->n_ul_current = sli->n_ul;
} else { } else {
LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n", LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n",
n_active_slices_uplink, n_active_slices_current_uplink); sli->n_ul, sli->n_ul_current);
n_active_slices_uplink = n_active_slices_current_uplink; sli->n_ul = sli->n_ul_current;
} }
} }
// check if the slice rb share has changed, and log the console // check if the slice rb share has changed, and log the console
if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ if (sli->ul[i].pct_current != sli->ul[i].pct){
LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n",
module_idP, i, frameP, subframeP, total_slice_percentage_current_uplink, module_idP, i, frameP, subframeP, sli->tot_pct_ul_current,
total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); sli->tot_pct_ul, sli->ul[i].pct_current, sli->ul[i].pct);
total_slice_percentage_current_uplink = total_slice_percentage_uplink; sli->tot_pct_ul_current = sli->tot_pct_ul;
slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; sli->ul[i].pct_current = sli->ul[i].pct;
} }
// check if the slice max MCS, and log the console // check if the slice max MCS, and log the console
if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ if (sli->ul[i].maxmcs_current != sli->ul[i].maxmcs){
if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 16)){
LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n",
module_idP, i, frameP, subframeP, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); module_idP, i, frameP, subframeP, sli->ul[i].maxmcs_current, sli->ul[i].maxmcs);
slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; sli->ul[i].maxmcs_current = sli->ul[i].maxmcs;
} else { } else {
LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n", LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",
module_idP, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); module_idP, i, sli->ul[i].maxmcs, sli->ul[i].maxmcs_current);
slice_maxmcs_uplink[i] = slice_maxmcs_current_uplink[i]; sli->ul[i].maxmcs = sli->ul[i].maxmcs_current;
} }
} }
if (slice_first_rb_current[i] != slice_first_rb[i]){ if (sli->ul[i].first_rb_current != sli->ul[i].first_rb){
if (slice_first_rb[i] >= 0){ // FIXME: Max limit is checked in the scheduler if (sli->ul[i].first_rb >= 0){ // FIXME: Max limit is checked in the scheduler
LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice first rb has changed: %d-->%d\n", LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice first rb has changed: %d-->%d\n",
module_idP, i, frameP, subframeP, slice_first_rb_current[i], slice_first_rb[i]); module_idP, i, frameP, subframeP, sli->ul[i].first_rb_current, sli->ul[i].first_rb);
slice_first_rb_current[i] = slice_first_rb[i]; sli->ul[i].first_rb_current = sli->ul[i].first_rb;
} else { } else {
LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n", LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n",
module_idP, i, slice_first_rb[i],slice_first_rb_current[i]); module_idP, i, sli->ul[i].first_rb, sli->ul[i].first_rb_current);
slice_first_rb[i] = slice_first_rb_current[i]; sli->ul[i].first_rb = sli->ul[i].first_rb_current;
} }
} }
// check if a new scheduler, and log the console // check if a new scheduler, and log the console
if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ if (sli->ul[i].update_sched_current != sli->ul[i].update_sched) {
LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n",
module_idP, i, frameP, subframeP, ul_scheduler_type[i]); module_idP, i, frameP, subframeP, sli->ul[i].sched_name);
update_ul_scheduler_current[i] = update_ul_scheduler[i]; sli->ul[i].update_sched_current = sli->ul[i].update_sched;
} }
} else { } else {
if (n_active_slices_uplink == n_active_slices_current_uplink) { if (sli->n_ul == sli->n_ul_current) {
LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
module_idP, i, total_slice_percentage_current_uplink, total_slice_percentage_uplink); module_idP, i, sli->tot_pct_ul_current, sli->tot_pct_ul);
if (slice_percentage_uplink[i] > avg_slice_percentage_uplink) { if (sli->ul[i].pct > sli->avg_pct_ul) {
slice_percentage_uplink[i] -= 0.1; sli->ul[i].pct -= 0.1;
total_slice_percentage_uplink -= 0.1; sli->tot_pct_ul -= 0.1;
} }
} else { } else {
// here we can correct the values, e.g. reduce proportionally // here we can correct the values, e.g. reduce proportionally
LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
module_idP, i, total_slice_percentage_current_uplink, module_idP, i, sli->tot_pct_ul_current,
total_slice_percentage_uplink, n_active_slices_uplink, sli->tot_pct_ul, sli->n_ul,
n_active_slices_current_uplink); sli->n_ul_current);
n_active_slices_uplink = n_active_slices_current_uplink; sli->n_ul = sli->n_ul_current;
slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; sli->ul[i].pct = sli->ul[i].pct_current;
} }
} }
// Run each enabled slice-specific schedulers one by one // Run each enabled slice-specific schedulers one by one
slice_sched_ul[i](module_idP, i, frameP, subframeP, sched_subframe, first_rb); sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb);
} }
stop_meas(&mac->schedule_ulsch); stop_meas(&mac->schedule_ulsch);
...@@ -1172,6 +1175,7 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1172,6 +1175,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
eNB_MAC_INST *mac = RC.mac[module_idP]; eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc = mac->common_channels; COMMON_channels_t *cc = mac->common_channels;
UE_list_t *UE_list = &mac->UE_list; UE_list_t *UE_list = &mac->UE_list;
slice_info_t *sli = &RC.mac[module_idP]->slice_info;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
UE_sched_ctrl *UE_sched_ctrl; UE_sched_ctrl *UE_sched_ctrl;
int sched_frame = frameP; int sched_frame = frameP;
...@@ -1193,7 +1197,7 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1193,7 +1197,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) {
N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth);
UE_list->first_rb_offset[CC_id][slice_id] = cmin(N_RB_UL, slice_first_rb[slice_id]); UE_list->first_rb_offset[CC_id][slice_id] = cmin(N_RB_UL, sli->ul[slice_id].first_rb);
} }
//LOG_D(MAC, "entering ulsch preprocesor\n"); //LOG_D(MAC, "entering ulsch preprocesor\n");
...@@ -1210,7 +1214,7 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1210,7 +1214,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
for (UE_id = UE_list->head_ul; UE_id >= 0; for (UE_id = UE_list->head_ul; UE_id >= 0;
UE_id = UE_list->next_ul[UE_id]) { UE_id = UE_list->next_ul[UE_id]) {
if (!ue_slice_membership(UE_id, slice_id)) if (!ue_slice_membership(UE_id, slice_id, sli->n_ul))
continue; continue;
// don't schedule if Msg4 is not received yet // don't schedule if Msg4 is not received yet
...@@ -1398,7 +1402,7 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1398,7 +1402,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
UE_template->oldNDI_UL[harq_pid] = ndi; UE_template->oldNDI_UL[harq_pid] = ndi;
UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power;
UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]); UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_id].maxmcs);
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid];
//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
if (UE_template->pre_allocated_rb_table_index_ul >= 0) { if (UE_template->pre_allocated_rb_table_index_ul >= 0) {
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file LAYER2/MAC/eNB_scheduler_ulsch.h
* \brief ULSCH Scheduler policy variables used during different phases of scheduling
* \author Navid Nikaein and Niccolo' Iardella
* \date 2018
* \version 0.2
* \email navid.nikaein@eurecom.fr
*/
/** @defgroup _oai2 openair2 Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
/*@}*/
#ifndef __LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__
#define __LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__
/* number of active slices for past and current time*/
int n_active_slices_uplink = 1;
int n_active_slices_current_uplink = 1;
/* RB share for each slice for past and current time*/
float avg_slice_percentage_uplink=0.25;
float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float total_slice_percentage_uplink = 0;
float total_slice_percentage_current_uplink = 0;
// MAX MCS for each slice for past and current time
int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20};
int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20};
int slice_first_rb[MAX_NUM_SLICES] = {0, 0, 0, 0};
int slice_first_rb_current[MAX_NUM_SLICES] = {0,0,0,0};
/*resource blocks allowed*/
uint16_t nb_rbs_allowed_slice_uplink[NFAPI_CC_MAX][MAX_NUM_SLICES];
/*Slice Update */
int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1};
int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1};
/* name of available scheduler*/
char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti",
"schedule_ulsch_rnti",
"schedule_ulsch_rnti",
"schedule_ulsch_rnti"
};
/* Slice Function Pointer */
slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0};
#endif //__LAYER2_MAC_ENB_SCHEDULER_ULSCH_H__
...@@ -1122,6 +1122,143 @@ typedef struct { ...@@ -1122,6 +1122,143 @@ typedef struct {
int tail_freelist; ///the tail position of the delete list int tail_freelist; ///the tail position of the delete list
} UE_free_list_t; } UE_free_list_t;
/// Structure for saving the output of each pre_processor instance
typedef struct {
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX];
uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID];
uint32_t wb_pmi[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint8_t mcs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
} pre_processor_results_t;
/**
* slice specific scheduler for the DL
*/
typedef void (*slice_scheduler_dl)(module_id_t mod_id,
slice_id_t slice_id,
frame_t frame,
sub_frame_t subframe,
int *mbsfn_flag);
typedef struct {
/// RB share for each slice for past and current time
float pct;
float pct_current;
/// whether this slice is isolated from the others for past and current time
int isol;
int isol_current;
int prio;
int prio_current;
/// Frequency ranges for slice positioning
int pos_low;
int pos_high;
int pos_low_current;
int pos_high_current;
// max mcs for each slice for past and current time
int maxmcs;
int maxmcs_current;
/// criteria for sorting policies of the slices
uint32_t sorting;
uint32_t sorting_current;
/// Accounting policy (just greedy(1) or fair(0) setting for now)
int accounting;
int accounting_current;
/// Whether the scheduler callback should be updated
int update_sched;
int update_sched_current;
/// name of available scheduler
char *sched_name;
/// pointer to the slice specific scheduler in DL
slice_scheduler_dl sched_cb;
} slice_sched_conf_dl_t;
typedef void (*slice_scheduler_ul)(module_id_t mod_id,
slice_id_t slice_id,
frame_t frame,
sub_frame_t subframe,
unsigned char sched_subframe,
uint16_t *first_rb);
typedef struct {
/// RB share for each slice for past and current time
float pct;
float pct_current;
// MAX MCS for each slice for past and current time
int maxmcs;
int maxmcs_current;
/// criteria for sorting policies of the slices
uint32_t sorting;
uint32_t sorting_current;
/// starting RB (RB offset) of UL scheduling
int first_rb;
int first_rb_current;
/// Slice scheduler callback update needed
int update_sched;
int update_sched_current;
/// name of available scheduler
char *sched_name;
/// pointer to the slice specific scheduler in UL
slice_scheduler_ul sched_cb;
} slice_sched_conf_ul_t;
typedef struct {
/// counter used to indicate when all slices have pre-allocated UEs
int slice_counter;
/// indicates whether remaining RBs after first intra-slice allocation will
/// be allocated to UEs of the same slice
int intraslice_share_active;
int intraslice_share_active_current;
/// indicates whether remaining RBs after slice allocation will be
/// allocated to UEs of another slice. Isolated slices will be ignored
int interslice_share_active;
int interslice_share_active_current;
/// number of active slices for past and current time in DL
int n_dl;
int n_dl_current;
/// RB share stats for DL
float tot_pct_dl;
float tot_pct_dl_current;
float avg_pct_dl;
slice_sched_conf_dl_t dl[MAX_NUM_SLICES];
/// number of active slices for past and current time in UL
int n_ul;
int n_ul_current;
/// RB share stats for UL
float tot_pct_ul;
float tot_pct_ul_current;
float avg_pct_ul;
slice_sched_conf_ul_t ul[MAX_NUM_SLICES];
pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
} slice_info_t;
/*! \brief eNB common channels */ /*! \brief eNB common channels */
typedef struct { typedef struct {
int physCellId; int physCellId;
...@@ -1242,7 +1379,10 @@ typedef struct eNB_MAC_INST_s { ...@@ -1242,7 +1379,10 @@ typedef struct eNB_MAC_INST_s {
/// UL handle /// UL handle
uint32_t ul_handle; uint32_t ul_handle;
UE_list_t UE_list; UE_list_t UE_list;
/// slice-related configuration
slice_info_t slice_info;
///subband bitmap configuration ///subband bitmap configuration
SBMAP_CONF sbmap_conf; SBMAP_CONF sbmap_conf;
/// CCE table used to build DCI scheduling information /// CCE table used to build DCI scheduling information
...@@ -1575,20 +1715,6 @@ typedef struct { ...@@ -1575,20 +1715,6 @@ typedef struct {
mui_t rrc_mui[128]; mui_t rrc_mui[128];
}mac_rlc_am_muilist_t; }mac_rlc_am_muilist_t;
/// Structure for saving the output of each pre_processor instance
typedef struct {
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX];
uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID];
uint32_t wb_pmi[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
uint8_t mcs[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
} pre_processor_results_t;
#include "mac_proto.h" #include "mac_proto.h"
/*@}*/ /*@}*/
......
...@@ -36,22 +36,6 @@ ...@@ -36,22 +36,6 @@
* @{ * @{
*/ */
/**
* slice specific scheduler
*/
typedef void (*slice_scheduler_dl)(module_id_t mod_id,
slice_id_t slice_id,
frame_t frame,
sub_frame_t subframe,
int *mbsfn_flag);
typedef void (*slice_scheduler_ul)(module_id_t mod_id,
slice_id_t slice_id,
frame_t frame,
sub_frame_t subframe,
unsigned char sched_subframe,
uint16_t *first_rb);
/** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
\brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -260,7 +244,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, ...@@ -260,7 +244,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t MIMO_mode_indicator[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 slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]);
void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
int frameP, int frameP,
...@@ -1278,7 +1262,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, ...@@ -1278,7 +1262,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP,
/*Slice related functions */ /*Slice related functions */
uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs);
int ue_slice_membership(int UE_id, int slice_id); int ue_slice_membership(int UE_id, int slice_id, int n_active_slices);
/* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */
uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe);
......
...@@ -52,6 +52,7 @@ void mac_top_init_eNB(void) ...@@ -52,6 +52,7 @@ void mac_top_init_eNB(void)
module_id_t i, j; module_id_t i, j;
int list_el; int list_el;
UE_list_t *UE_list; UE_list_t *UE_list;
slice_info_t *sli;
eNB_MAC_INST *mac; eNB_MAC_INST *mac;
LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n",
...@@ -112,7 +113,7 @@ void mac_top_init_eNB(void) ...@@ -112,7 +113,7 @@ void mac_top_init_eNB(void)
RC.mac = NULL; RC.mac = NULL;
} }
// Initialize Linked-List for Active UEs // Initialize Linked-List for Active UEs and slice configuration
for (i = 0; i < RC.nb_macrlc_inst; i++) { for (i = 0; i < RC.nb_macrlc_inst; i++) {
mac = RC.mac[i]; mac = RC.mac[i];
...@@ -133,6 +134,49 @@ void mac_top_init_eNB(void) ...@@ -133,6 +134,49 @@ void mac_top_init_eNB(void)
UE_list->next[list_el] = -1; UE_list->next[list_el] = -1;
UE_list->next_ul[list_el] = -1; UE_list->next_ul[list_el] = -1;
sli = &mac->slice_info;
sli->intraslice_share_active = 1;
sli->intraslice_share_active_current = 1;
sli->interslice_share_active = 1;
sli->interslice_share_active_current = 1;
sli->n_dl = 1;
sli->n_dl_current = 1;
sli->tot_pct_dl = 1;
sli->tot_pct_dl_current = 1;
sli->avg_pct_dl = 0.25;
memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES);
sli->dl[0].pct = 1.0;
sli->dl[0].pct_current = 1.0;
sli->dl[0].prio = 10;
sli->dl[0].prio_current = 10;
sli->dl[0].pos_high = N_RBG_MAX;
sli->dl[0].pos_high_current = N_RBG_MAX;
sli->dl[0].maxmcs = 28;
sli->dl[0].maxmcs_current = 28;
sli->dl[0].sorting = 0x012345;
sli->dl[0].sorting_current = 0x012345;
sli->dl[0].update_sched = 1;
sli->dl[0].update_sched_current = 1;
sli->dl[0].sched_name = "schedule_ue_spec";
sli->n_ul = 1;
sli->n_ul_current = 1;
sli->tot_pct_ul = 1;
sli->tot_pct_ul_current = 1;
sli->avg_pct_ul = 0.25;
memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES);
sli->ul[0].pct = 1.0;
sli->ul[0].pct_current = 1.0;
sli->ul[0].maxmcs = 20;
sli->ul[0].maxmcs_current = 20;
sli->ul[0].sorting = 0x0123;
sli->ul[0].sorting_current = 0x0123;
sli->ul[0].update_sched = 1;
sli->ul[0].update_sched_current = 1;
sli->ul[0].sched_name = "schedule_ulsch_rnti";
} }
} }
......
...@@ -54,17 +54,6 @@ extern RAN_CONTEXT_t RC; ...@@ -54,17 +54,6 @@ extern RAN_CONTEXT_t RC;
#define DEBUG_HEADER_PARSING 1 #define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1 //#define DEBUG_PACKET_TRACE 1
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[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];
extern int intraslice_share_active;
//#define ICIC 0 //#define ICIC 0
/* this function checks that get_eNB_UE_stats returns /* this function checks that get_eNB_UE_stats returns
...@@ -113,7 +102,7 @@ store_dlsch_buffer(module_id_t Mod_id, ...@@ -113,7 +102,7 @@ store_dlsch_buffer(module_id_t Mod_id,
if (UE_list->active[UE_id] != TRUE) if (UE_list->active[UE_id] != TRUE)
continue; continue;
if (!ue_slice_membership(UE_id, slice_id)) if (!ue_slice_membership(UE_id, slice_id, RC.mac[Mod_id]->slice_info.n_dl))
continue; continue;
UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id];
...@@ -196,13 +185,14 @@ assign_rbs_required(module_id_t Mod_id, ...@@ -196,13 +185,14 @@ assign_rbs_required(module_id_t Mod_id,
int UE_id, n, i, j, CC_id, pCCid, tmp; int UE_id, n, i, j, CC_id, pCCid, tmp;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j;
int N_RB_DL; int N_RB_DL;
// clear rb allocations across all CC_id // clear rb allocations across all CC_id
for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue; if (UE_list->active[UE_id] != TRUE) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
pCCid = UE_PCCID(Mod_id, UE_id); pCCid = UE_PCCID(Mod_id, UE_id);
//update CQI information across component carriers //update CQI information across component carriers
...@@ -210,8 +200,8 @@ assign_rbs_required(module_id_t Mod_id, ...@@ -210,8 +200,8 @@ assign_rbs_required(module_id_t Mod_id,
CC_id = UE_list->ordered_CCids[n][UE_id]; CC_id = UE_list->ordered_CCids[n][UE_id];
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], slice_maxmcs[slice_id]); // eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_id].maxmcs);
eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), slice_maxmcs[slice_id]); eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_id].maxmcs);
} }
...@@ -254,7 +244,7 @@ assign_rbs_required(module_id_t Mod_id, ...@@ -254,7 +244,7 @@ assign_rbs_required(module_id_t Mod_id,
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] =
nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); nb_rbs_allowed_slice(sli->dl[slice_id].pct, N_RB_DL);
/* calculating required number of RBs for each UE */ /* calculating required number of RBs for each UE */
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
...@@ -274,7 +264,7 @@ assign_rbs_required(module_id_t Mod_id, ...@@ -274,7 +264,7 @@ assign_rbs_required(module_id_t Mod_id,
nb_rbs_required[CC_id][UE_id], TBS, nb_rbs_required[CC_id][UE_id], TBS,
eNB_UE_stats->dlsch_mcs1); eNB_UE_stats->dlsch_mcs1);
pre_processor_results[slice_id].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; sli->pre_processor_results[slice_id].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1;
} }
} }
} }
...@@ -435,7 +425,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { ...@@ -435,7 +425,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) {
int i; int i;
UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
uint32_t policy = slice_sorting[slice_id]; uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_id].sorting;
uint32_t mask = 0x0000000F; uint32_t mask = 0x0000000F;
uint16_t criterion; uint16_t criterion;
...@@ -443,7 +433,7 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { ...@@ -443,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); criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask);
if (criterion >= CR_NUM) { if (criterion >= CR_NUM) {
LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id);
slice_sorting[slice_id] = 0x12345; RC.mac[Mod_idP]->slice_info.dl[slice_id].sorting = 0x12345;
break; break;
} }
UE_list->sorting_criteria[slice_id][i] = criterion; UE_list->sorting_criteria[slice_id][i] = criterion;
...@@ -463,8 +453,8 @@ void decode_slice_positioning(module_id_t Mod_idP, ...@@ -463,8 +453,8 @@ void decode_slice_positioning(module_id_t Mod_idP,
} }
} }
start_frequency = slice_position[slice_id*2]; start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_id].pos_low;
end_frequency = slice_position[slice_id*2 + 1]; end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_id].pos_high;
for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) {
for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { for (RBG = start_frequency; RBG <= end_frequency; ++RBG) {
slice_allocation_mask[CC_id][RBG] = 1; slice_allocation_mask[CC_id][RBG] = 1;
...@@ -488,7 +478,7 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t ...@@ -488,7 +478,7 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t
if (UE_list->active[i] == FALSE) continue; if (UE_list->active[i] == FALSE) continue;
if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(i, slice_id)) continue; if (!ue_slice_membership(i, slice_id, RC.mac[Mod_idP]->slice_info.n_dl)) continue;
list[list_size] = i; list[list_size] = i;
list_size++; list_size++;
...@@ -592,14 +582,14 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, ...@@ -592,14 +582,14 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, RC.mac[Mod_id]->slice_info.n_dl)) continue;
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
available_rbs = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_id].pct, N_RB_DL);
if (rbs_retx[CC_id] < available_rbs) if (rbs_retx[CC_id] < available_rbs)
ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = available_rbs - rbs_retx[CC_id]; ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = available_rbs - rbs_retx[CC_id];
else else
...@@ -630,6 +620,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -630,6 +620,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
COMMON_channels_t *cc; COMMON_channels_t *cc;
...@@ -650,7 +641,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -650,7 +641,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
rnti = UE_RNTI(Mod_id, UE_id); rnti = UE_RNTI(Mod_id, UE_id);
if (rnti == NOT_A_RNTI) continue; if (rnti == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
...@@ -682,7 +673,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -682,7 +673,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
// Reduces the available RBs according to slicing configuration // Reduces the available RBs according to slicing configuration
dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx);
switch (slice_accounting[slice_id]) { switch (RC.mac[Mod_id]->slice_info.dl[slice_id].accounting) {
// If greedy scheduling, try to account all the required RBs // If greedy scheduling, try to account all the required RBs
case POL_GREEDY: case POL_GREEDY:
...@@ -690,7 +681,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -690,7 +681,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
rnti = UE_RNTI(Mod_id, UE_id); rnti = UE_RNTI(Mod_id, UE_id);
if (rnti == NOT_A_RNTI) continue; if (rnti == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
...@@ -710,7 +701,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -710,7 +701,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
if (rnti == NOT_A_RNTI) continue; if (rnti == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
...@@ -735,7 +726,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -735,7 +726,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
rnti = UE_RNTI(Mod_id, UE_id); rnti = UE_RNTI(Mod_id, UE_id);
if (rnti == NOT_A_RNTI) continue; if (rnti == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
...@@ -754,7 +745,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -754,7 +745,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
rnti = UE_RNTI(Mod_id, UE_id); rnti = UE_RNTI(Mod_id, UE_id);
if (rnti == NOT_A_RNTI) continue; if (rnti == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
...@@ -789,6 +780,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, ...@@ -789,6 +780,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id,
int N_RBG[NFAPI_CC_MAX]; int N_RBG[NFAPI_CC_MAX];
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask);
...@@ -802,7 +794,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, ...@@ -802,7 +794,7 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id,
if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
...@@ -1011,9 +1003,10 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, ...@@ -1011,9 +1003,10 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
int UE_id, CC_id; int UE_id, CC_id;
int i; int i;
uint8_t transmission_mode; uint8_t transmission_mode;
uint8_t (*slice_allocation_mask)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocation_mask;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
int N_RBG[NFAPI_CC_MAX]; int N_RBG[NFAPI_CC_MAX];
slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_id].slice_allocation_mask;
decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask);
...@@ -1027,7 +1020,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, ...@@ -1027,7 +1020,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
if (!ue_slice_membership(UE_id, slice_id)) continue; if (!ue_slice_membership(UE_id, slice_id, sli->n_dl)) continue;
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
...@@ -1241,11 +1234,12 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, ...@@ -1241,11 +1234,12 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
int min_rb_unit[NFAPI_CC_MAX]; int min_rb_unit[NFAPI_CC_MAX];
uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_required; slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_accounted; uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_required;
uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_remaining; uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_accounted;
uint8_t (*rballoc_sub)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocated_rbgs; uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_id].nb_rbs_remaining;
uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = pre_processor_results[slice_id].MIMO_mode_indicator; uint8_t (*rballoc_sub)[N_RBG_MAX] = sli->pre_processor_results[slice_id].slice_allocated_rbgs;
uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_id].MIMO_mode_indicator;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
...@@ -1263,7 +1257,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, ...@@ -1263,7 +1257,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
#endif #endif
// Initialize scheduling information for all active UEs // Initialize scheduling information for all active UEs
memset(&pre_processor_results[slice_id], 0, sizeof(pre_processor_results)); memset(&sli->pre_processor_results[slice_id], 0, sizeof(sli->pre_processor_results));
// FIXME: After the memset above, some of the resets in reset() are redundant // FIXME: After the memset above, some of the resets in reset() are redundant
dlsch_scheduler_pre_processor_reset(Mod_id, slice_id, frameP, subframeP, dlsch_scheduler_pre_processor_reset(Mod_id, slice_id, frameP, subframeP,
min_rb_unit, min_rb_unit,
...@@ -1302,7 +1296,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, ...@@ -1302,7 +1296,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
// SHARING // SHARING
// If there are available RBs left in the slice, allocate them to the highest priority UEs // If there are available RBs left in the slice, allocate them to the highest priority UEs
if (intraslice_share_active) { if (RC.mac[Mod_id]->slice_info.intraslice_share_active) {
dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id, dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_id,
min_rb_unit, min_rb_unit,
nb_rbs_required, nb_rbs_required,
...@@ -1411,6 +1405,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, ...@@ -1411,6 +1405,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
rnti_t rnti; rnti_t rnti;
UE_list_t *UE_list; UE_list_t *UE_list;
slice_info_t *sli = &RC.mac[module_idP]->slice_info;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
uint8_t *vrb_map; uint8_t *vrb_map;
COMMON_channels_t *cc; COMMON_channels_t *cc;
...@@ -1440,7 +1435,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, ...@@ -1440,7 +1435,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
if (UE_list->active[UE_id] != TRUE) if (UE_list->active[UE_id] != TRUE)
continue; continue;
if (!ue_slice_membership(UE_id, slice_id)) if (!ue_slice_membership(UE_id, slice_id, sli->n_dl))
continue; continue;
vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
...@@ -1674,7 +1669,6 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1674,7 +1669,6 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
unsigned char sched_subframeP, unsigned char sched_subframeP,
uint16_t *first_rb) uint16_t *first_rb)
{ {
int16_t i; int16_t i;
uint16_t UE_id, n, r; uint16_t UE_id, n, r;
uint8_t CC_id, harq_pid; uint8_t CC_id, harq_pid;
...@@ -1685,6 +1679,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1685,6 +1679,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
uint16_t total_ue_count[NFAPI_CC_MAX]; uint16_t total_ue_count[NFAPI_CC_MAX];
rnti_t rnti = -1; rnti_t rnti = -1;
UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
slice_info_t *sli = &RC.mac[module_idP]->slice_info;
UE_TEMPLATE *UE_template = 0; UE_TEMPLATE *UE_template = 0;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
int N_RB_UL = 0; int N_RB_UL = 0;
...@@ -1714,7 +1709,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1714,7 +1709,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][i]; CC_id = UE_list->ordered_ULCCids[n][i];
UE_template = &UE_list->UE_template[CC_id][i]; UE_template = &UE_list->UE_template[CC_id][i];
if (!ue_slice_membership(i, slice_id)) if (!ue_slice_membership(i, slice_id, sli->n_ul))
continue; continue;
if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) {
total_ue_count[CC_id] += 1; total_ue_count[CC_id] += 1;
...@@ -1735,7 +1730,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1735,7 +1730,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
if (!ue_slice_membership(UE_id, slice_id)) if (!ue_slice_membership(UE_id, slice_id, sli->n_ul))
continue; continue;
LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id,
...@@ -1760,7 +1755,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1760,7 +1755,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth);
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] =
nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); nb_rbs_allowed_slice(sli->ul[slice_id].pct, N_RB_UL);
first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id]; first_rb_offset = UE_list->first_rb_offset[CC_id][slice_id];
available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id], available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id],
...@@ -1792,7 +1787,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1792,7 +1787,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
if (!ue_slice_membership(i, slice_id)) if (!ue_slice_membership(i, slice_id, sli->n_ul))
continue; continue;
...@@ -1833,7 +1828,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1833,7 +1828,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
if (!ue_slice_membership(i, slice_id)) if (!ue_slice_membership(i, slice_id, sli->n_ul))
continue; continue;
UE_id = i; UE_id = i;
...@@ -1892,6 +1887,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, ...@@ -1892,6 +1887,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP,
int rb_table_index = 0, tbs, tx_power; int rb_table_index = 0, tbs, tx_power;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
slice_info_t *sli = &RC.mac[module_idP]->slice_info;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
...@@ -1909,16 +1905,16 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, ...@@ -1909,16 +1905,16 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP,
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
if (!ue_slice_membership(i, slice_id)) if (!ue_slice_membership(i, slice_id, sli->n_ul))
continue; continue;
if (UE_list->UE_sched_ctrl[i].phr_received == 1) { if (UE_list->UE_sched_ctrl[i].phr_received == 1) {
/* if we've received the power headroom information the UE, we can go to /* if we've received the power headroom information the UE, we can go to
* maximum mcs */ * maximum mcs */
mcs = cmin(20, slice_maxmcs_uplink[slice_id]); mcs = cmin(20, sli->ul[slice_id].maxmcs);
} else { } else {
/* otherwise, limit to QPSK PUSCH */ /* otherwise, limit to QPSK PUSCH */
mcs = cmin(10, slice_maxmcs_uplink[slice_id]); mcs = cmin(10, sli->ul[slice_id].maxmcs);
} }
UE_id = i; UE_id = i;
...@@ -1941,7 +1937,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, ...@@ -1941,7 +1937,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP,
Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp;
N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth);
ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] =
nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], N_RB_UL); nb_rbs_allowed_slice(sli->ul[slice_id].pct, N_RB_UL);
int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes;
if (bytes_to_schedule < 0) bytes_to_schedule = 0; if (bytes_to_schedule < 0) bytes_to_schedule = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment