Commit 21f66094 authored by Robert Schmidt's avatar Robert Schmidt

FlexRAN: move slice param verification to agent

- until now, on every iteration, the scheduler checked for changed parameter
  (and verified some)
- this functionality moves to the FlexRAN Agent, which verifies all parameters
  * individually, e.g. Max MCS <= 28 for DL
  * group-based, e.g. the sum of slice percentages is <= 100
- slice configuration changes are only applied if all verifications pass
- it is assumed in the scheduler, that configuration passed from outside is
  correct and can be used "as-is"

fix accounting setting
parent 6b3dd871
...@@ -870,6 +870,7 @@ add_library(FLEXRAN_AGENT ...@@ -870,6 +870,7 @@ add_library(FLEXRAN_AGENT
${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c
${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c
) )
set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT)
#include_directories(${OPENAIR2_DIR}/ENB_APP) #include_directories(${OPENAIR2_DIR}/ENB_APP)
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "flexran_agent_common_internal.h" #include "flexran_agent_common_internal.h"
#include "flexran_agent_mac_internal.h" #include "flexran_agent_mac_internal.h"
#include "flexran_agent_mac_slice_verification.h"
/* from flexran_agent_mac.c */ /* from flexran_agent_mac.c */
extern Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB]; extern Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB];
...@@ -1141,107 +1142,203 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli ...@@ -1141,107 +1142,203 @@ void overwrite_slice_config_ul(Protocol__FlexUlSlice *exist, Protocol__FlexUlSli
} }
} }
void prepare_update_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *dls) void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s)
{ {
if (!dls->has_id) { /* TODO fill the slice depending on the chosen label */
LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); /* for now, we fill it up with the information from slice 0 */
return; /* assume there is an ID (will be checked later) */
} if (!s->has_label) {
/* a percentage of zero will be interpreted as removal command */ s->has_label = 1;
if (sc_update[mod_id]->n_dl >= MAX_NUM_SLICES s->label = sc_update[mod_id]->dl[0]->label;
&& (!dls->has_percentage || dls->percentage > 0)) { }
LOG_E(FLEXRAN_AGENT, "[%d] Cannot create more than %ld slices in DL\n", if (!s->has_percentage) {
mod_id, sc_update[mod_id]->n_dl); s->has_percentage = 1;
return; s->percentage = sc_update[mod_id]->dl[0]->percentage;
} }
if (sc_update[mod_id]->n_dl == 1 && dls->has_percentage && dls->percentage == 0) { if (!s->has_isolation) {
LOG_E(FLEXRAN_AGENT, "[%d] Cannot delete last slice ID %d in DL\n", s->has_isolation = 1;
mod_id, sc_update[mod_id]->dl[0]->id); s->isolation = sc_update[mod_id]->dl[0]->isolation;
return; }
} if (!s->has_priority) {
s->has_priority = 1;
s->priority = sc_update[mod_id]->dl[0]->priority;
}
if (!s->has_position_low) {
s->has_position_low = 1;
s->position_low = sc_update[mod_id]->dl[0]->position_low;
}
if (!s->has_position_high) {
s->has_position_high = 1;
s->position_high = sc_update[mod_id]->dl[0]->position_high;
}
if (!s->has_maxmcs) {
s->has_maxmcs = 1;
s->maxmcs = sc_update[mod_id]->dl[0]->maxmcs;
}
if (s->n_sorting == 0) {
s->n_sorting = sc_update[0]->dl[0]->n_sorting;
/* TODO Dangerous? */
s->sorting = sc_update[0]->dl[0]->sorting;
}
if (!s->has_accounting) {
/* TODO Dangerous? */
s->accounting = sc_update[0]->dl[0]->accounting;
}
/* scheduler name not set, cannot be changed for the moment */
}
Protocol__FlexDlSlice *to = NULL; Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id)
{
for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) { for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) {
if (dls->id == sc_update[mod_id]->dl[i]->id) { if (id == sc_update[mod_id]->dl[i]->id) {
to = sc_update[mod_id]->dl[i]; return sc_update[mod_id]->dl[i];
break;
} }
} }
return NULL;
}
/* create new slice -> read contents from existing slice config index 0 */ Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id)
if (!to) { {
LOG_I(FLEXRAN_AGENT, LOG_I(FLEXRAN_AGENT,
"[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n",
mod_id, dls->id); mod_id, id);
to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl];
sc_update[mod_id]->n_dl++; sc_update[mod_id]->n_dl++;
memcpy(to, slice_config[mod_id]->dl[0], sizeof(*to)); AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES,
to->id = dls->id; "cannot create more than MAX_NUM_SLICES\n");
} to->id = id;
return to;
overwrite_slice_config_dl(to, dls);
} }
void prepare_update_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *uls) void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s)
{ {
if (!uls->has_id) { /* TODO fill the slice depending on the chosen label */
LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); /* for now, we fill it up with the information from slice 0 */
return; /* assume there is an ID (will be checked later) */
} if (!s->has_label) {
/* a percentage of zero will be interpreted as removal command */ s->has_label = 1;
if (sc_update[mod_id]->n_ul >= MAX_NUM_SLICES s->label = sc_update[mod_id]->ul[0]->label;
&& (!uls->has_percentage || uls->percentage > 0)) { }
LOG_E(FLEXRAN_AGENT, "[%d] Cannot create more than %ld slices in UL\n", if (!s->has_percentage) {
mod_id, sc_update[mod_id]->n_ul); s->has_percentage = 1;
return; s->percentage = sc_update[mod_id]->ul[0]->percentage;
} }
if (sc_update[mod_id]->n_ul == 1 && uls->has_percentage && uls->percentage == 0) { if (!s->has_isolation) {
LOG_E(FLEXRAN_AGENT, "[%d] Cannot delete last slice ID %d in UL\n", s->has_isolation = 1;
mod_id, sc_update[mod_id]->ul[0]->id); s->isolation = sc_update[mod_id]->ul[0]->isolation;
return; }
} if (!s->has_priority) {
s->has_priority = 1;
s->priority = sc_update[mod_id]->ul[0]->priority;
}
if (!s->has_first_rb) {
s->has_first_rb = 1;
s->first_rb = sc_update[mod_id]->ul[0]->first_rb;
}
if (!s->has_maxmcs) {
s->has_maxmcs = 1;
s->maxmcs = sc_update[mod_id]->ul[0]->maxmcs;
}
if (s->n_sorting == 0) {
s->n_sorting = sc_update[0]->ul[0]->n_sorting;
/* TODO Dangerous? */
s->sorting = sc_update[0]->ul[0]->sorting;
}
if (!s->has_accounting) {
/* TODO Dangerous? */
s->accounting = sc_update[0]->ul[0]->accounting;
}
/* scheduler name not set, cannot be changed for the moment */
}
Protocol__FlexUlSlice *to = NULL; Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id)
{
for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) { for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) {
if (uls->id == sc_update[mod_id]->ul[i]->id) { if (id == sc_update[mod_id]->ul[i]->id) {
to = sc_update[mod_id]->ul[i]; return sc_update[mod_id]->ul[i];
break;
} }
} }
return NULL;
}
/* create new slice -> read contents from existing slice config index 0 */ Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id)
if (!to) { {
LOG_I(FLEXRAN_AGENT, LOG_I(FLEXRAN_AGENT,
"[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n",
mod_id, uls->id); mod_id, id);
to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul];
sc_update[mod_id]->n_ul++; sc_update[mod_id]->n_ul++;
memcpy(to, slice_config[mod_id]->ul[0], sizeof(*to)); AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES,
to->id = uls->id; "cannot create more than MAX_NUM_SLICES\n");
} to->id = id;
return to;
overwrite_slice_config_ul(to, uls);
} }
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice) void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup)
{ {
int verified = 1;
if (!sc_update[mod_id]) { if (!sc_update[mod_id]) {
LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n");
return; return;
} }
pthread_mutex_lock(&sc_update_mtx); pthread_mutex_lock(&sc_update_mtx);
if (sup->n_dl == 0) {
if (slice->n_dl == 0)
LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id);
for (int i = 0; i < slice->n_dl; i++) } else {
prepare_update_slice_config_dl(mod_id, slice->dl[i]); /* verify slice parameters */
for (int i = 0; i < sup->n_dl; i++) {
fill_dl_slice(mod_id, sup->dl[i]);
verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]);
if (!verified) break;
}
if (slice->n_ul == 0) /* verify group-based parameters (e.g. sum percentage should not exceed
* 100%). Can be used to perform admission control */
verified = verified && flexran_verify_group_dl_slices(mod_id,
sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl);
if (verified) {
for (int i = 0; i < sup->n_dl; i++) {
/* if all verifications were successful, get existing slice for ID or
* create new one and overwrite with the update */
Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id);
if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id);
overwrite_slice_config_dl(dls, sup->dl[i]);
}
} else {
LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id);
}
}
verified = 1;
if (sup->n_ul == 0) {
LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id); LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id);
for (int i = 0; i < slice->n_ul; i++) } else {
prepare_update_slice_config_ul(mod_id, slice->ul[i]); /* verify slice parameters */
for (int i = 0; i < sup->n_ul; i++) {
fill_ul_slice(mod_id, sup->ul[i]);
verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]);
if (!verified) break;
}
/* verify group-based parameters (e.g. sum percentage should not exceed
* 100%). Can be used to perform admission control */
verified = verified && flexran_verify_group_ul_slices(mod_id,
sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul);
if (verified) {
for (int i = 0; i < sup->n_ul; i++) {
/* if all verifications were successful, get existing slice for ID or
* create new one and overwrite with the update */
Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id);
if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id);
overwrite_slice_config_ul(uls, sup->ul[i]);
}
} else {
LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id);
}
}
pthread_mutex_unlock(&sc_update_mtx); pthread_mutex_unlock(&sc_update_mtx);
/* perform the slice configuration reads a couple of times. If there are /* perform the slice configuration reads a couple of times. If there are
...@@ -1299,11 +1396,6 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco ...@@ -1299,11 +1396,6 @@ int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protoco
flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting);
changes++; changes++;
} }
if (strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the DL scheduler is not supported, reverting\n",
mod_id, newc->id);
newc->scheduler_name = oldc->scheduler_name;
}
return changes; return changes;
} }
...@@ -1365,11 +1457,6 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco ...@@ -1365,11 +1457,6 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n",
mod_id, slice_idx); mod_id, slice_idx);
} }
if (strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the UL scheduler is not supported, reverting\n",
mod_id, slice_idx);
newc->scheduler_name = oldc->scheduler_name;
}
return changes; return changes;
} }
......
/*
* 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 flexran_agent_mac_slice_verification.c
* \brief MAC Agent slice verification helper functions
* \author Robert Schmidt
* \date 2018
* \version 0.1
*/
#include "flexran_agent_mac_slice_verification.h"
/* overlap check for UL slices, helper type */
struct sregion_s {
int start;
int length;
};
/* forward declaration of locally-used verification functions */
int flexran_dl_slice_verify_pct(int pct);
int flexran_dl_slice_verify_priority(int prio);
int flexran_dl_slice_verify_position(int pos_low, int pos_high);
int flexran_dl_slice_verify_maxmcs(int maxmcs);
int flexran_ul_slice_verify_pct(int pct);
int flexran_ul_slice_verify_priority(int prio);
int flexran_ul_slice_verify_first_rb(int first_rb);
int flexran_ul_slice_verify_maxmcs(int maxmcs);
int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n);
int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls)
{
/* check mandatory parameters */
if (!dls->has_id) {
LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id);
return 0;
}
/* verify parameters individualy */
/* label is enum */
if (!flexran_dl_slice_verify_pct(dls->percentage)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice percentage (%d)\n", mod_id, dls->percentage);
return 0;
}
/* isolation is a protobuf bool */
if (!flexran_dl_slice_verify_priority(dls->priority)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice priority (%d)\n", mod_id, dls->priority);
return 0;
}
if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice position low (%d) and/or high (%d)\n",
mod_id, dls->position_low, dls->position_high);
return 0;
}
if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal DL slice max mcs %d\n", mod_id, dls->maxmcs);
return 0;
}
if (dls->n_sorting == 0) {
LOG_E(FLEXRAN_AGENT, "[%d] no sorting in DL slice", mod_id);
return 0;
}
if (!dls->sorting) {
LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in DL slice\n", mod_id);
return 0;
}
/* sorting is an enum */
/* accounting is an enum */
if (dls->scheduler_name) {
LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler is not allowed\n", mod_id);
return 0;
}
return 1;
}
int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing,
int n_ex, Protocol__FlexDlSlice **update, int n_up)
{
int i, j, n;
int pct, pct_orig;
/* for every update, array points to existing slice, or NULL if update
* creates new slice */
Protocol__FlexDlSlice *s[n_up];
for (i = 0; i < n_up; i++) {
s[i] = NULL;
for (j = 0; j < n_ex; j++) {
if (existing[j]->id == update[i]->id)
s[i] = existing[j];
}
}
/* check that number of created and number of added slices in total matches
* [1,10] */
n = n_ex;
for (i = 0; i < n_up; i++) {
/* new slice */
if (!s[i]) n += 1;
/* slice will be deleted */
else if (s[i]->percentage == 0) n -= 1;
/* else "only" an update */
}
if (n < 1 || n > MAX_NUM_SLICES) {
LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting slices (%d -> %d)\n", mod_id, n_ex, n);
return 0;
}
/* check that the sum of all slices percentages (including removed/added
* slices) matches [1,100] */
pct = 0;
for (i = 0; i < n_ex; i++) {
pct += existing[i]->percentage;
}
pct_orig = pct;
for (i = 0; i < n_up; i++) {
/* if there is an existing slice, subtract its percentage and add the
* update's percentage */
if (s[i])
pct -= s[i]->percentage;
pct += update[i]->percentage;
}
if (pct < 1 || pct > 100) {
LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", mod_id, pct_orig, pct);
return 0;
}
return 1;
}
int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls)
{
/* check mandatory parameters */
if (!uls->has_id) {
LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id);
return 0;
}
/* verify parameters individually */
/* label is enum */
if (!flexran_ul_slice_verify_pct(uls->percentage)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice percentage (%d)\n", mod_id, uls->percentage);
return 0;
}
/* isolation is a protobuf bool */
if (!flexran_ul_slice_verify_priority(uls->priority)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice percentage (%d)\n", mod_id, uls->priority);
return 0;
}
if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice first RB (%d)\n", mod_id, uls->first_rb);
return 0;
}
if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) {
LOG_E(FLEXRAN_AGENT, "[%d] illegal UL slice max mcs (%d)\n", mod_id, uls->maxmcs);
return 0;
}
if (uls->n_sorting == 0) {
LOG_E(FLEXRAN_AGENT, "[%d] no sorting in UL slice\n", mod_id);
return 0;
}
if (!uls->sorting) {
LOG_E(FLEXRAN_AGENT, "[%d] no sorting found in UL slice\n", mod_id);
return 0;
}
/* sorting is an enum */
/* accounting is an enum */
if (uls->scheduler_name) {
LOG_E(FLEXRAN_AGENT, "[%d] setting the scheduler is not allowed\n", mod_id);
return 0;
}
return 1;
}
int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing,
int n_ex, Protocol__FlexUlSlice **update, int n_up)
{
int i, j, n;
int pct, pct_orig;
/* for every update, array "s" points to existing slice, or NULL if update
* creates new slice; array "offs" gives the offset of this slice */
Protocol__FlexUlSlice *s[n_up];
int offs[n_up];
for (i = 0; i < n_up; i++) {
s[i] = NULL;
offs[i] = 0;
for (j = 0; j < n_ex; j++) {
if (existing[j]->id == update[i]->id) {
s[i] = existing[j];
offs[i] = j;
}
}
}
/* check that number of created and number of added slices in total matches
* [1,10] */
n = n_ex;
for (i = 0; i < n_up; i++) {
/* new slice */
if (!s[i]) n += 1;
/* slice will be deleted */
else if (s[i]->percentage == 0) n -= 1;
/* else "only" an update */
}
if (n < 1 || n > MAX_NUM_SLICES) {
LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting slices (%d -> %d)\n", mod_id, n_ex, n);
return 0;
}
/* check that the sum of all slices percentages (including removed/added
* slices) matches [1,100] */
pct = 0;
for (i = 0; i < n_ex; i++) {
pct += existing[i]->percentage;
}
pct_orig = pct;
for (i = 0; i < n_up; i++) {
/* if there is an existing slice, subtract its percentage and add the
* update's percentage */
if (s[i])
pct -= s[i]->percentage;
pct += update[i]->percentage;
}
if (pct < 1 || pct > 100) {
LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", mod_id, pct_orig, pct);
return 0;
}
/* check that there is no overlap in slices resulting as the combination of
* first_rb and percentage */
struct sregion_s sregion[n];
const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */
int k = n_ex;
for (i = 0; i < n_ex; i++) {
sregion[i].start = existing[i]->first_rb;
sregion[i].length = existing[i]->percentage * N_RB / 100;
}
for (i = 0; i < n_up; i++) {
ptrdiff_t d = s[i] ? offs[i] : k++;
AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k);
sregion[d].start = update[i]->first_rb;
sregion[d].length = update[i]->percentage * N_RB / 100;
}
AssertFatal(k == n, "illegal number of slices while calculating overlap\n");
if (!check_ul_slice_overlap(mod_id, sregion, k)) {
LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id);
return 0;
}
return 1;
}
int flexran_dl_slice_verify_pct(int pct)
{
return pct >= 0 && pct <= 100;
}
int flexran_dl_slice_verify_priority(int prio)
{
return prio >= 0;
}
int flexran_dl_slice_verify_position(int pos_low, int pos_high)
{
return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX;
}
int flexran_dl_slice_verify_maxmcs(int maxmcs)
{
return maxmcs >= 0 && maxmcs <= 28;
}
int flexran_ul_slice_verify_pct(int pct)
{
return pct >= 0 && pct <= 100;
}
int flexran_ul_slice_verify_priority(int prio)
{
return prio >= 0;
}
int flexran_ul_slice_verify_first_rb(int first_rb)
{
return first_rb >= 0 && first_rb < 100;
}
int flexran_ul_slice_verify_maxmcs(int maxmcs)
{
return maxmcs >= 0 && maxmcs <= 20;
}
int sregion_compare(const void *_a, const void *_b)
{
const struct sregion_s *a = (const struct sregion_s *)_a;
const struct sregion_s *b = (const struct sregion_s *)_b;
const int res = a->start - b->start;
if (res < 0) return -1;
else if (res == 0) return 0;
else return 1;
}
int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n)
{
int i;
int overlap, op, u;
const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */
qsort(sr, n, sizeof(sr[0]), sregion_compare);
for (i = 0; i < n; i++) {
u = i == n-1 ? N_RB : sr[i+1].start;
AssertFatal(sr[i].start <= u, "unsorted slice list\n");
overlap = sr[i].start + sr[i].length - u;
if (overlap <= 0) continue;
op = overlap * 100 / sr[i].length;
LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op);
if (op >= 10) /* more than 10% overlap -> refuse */
return 0;
}
return 1;
}
/*
* 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 flexran_agent_mac_slice_verification.h
* \brief MAC Agent slice verification helper functions
* \author Robert Schmidt
* \date 2018
* \version 0.1
*/
#include "flexran_agent_common_internal.h"
#include "flexran_agent_mac_internal.h"
int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls);
int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing,
int n_ex, Protocol__FlexDlSlice **update, int n_up);
int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls);
int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing,
int n_ex, Protocol__FlexUlSlice **update, int n_up);
...@@ -414,193 +414,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -414,193 +414,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
slice_info_t *sli = &RC.mac[module_idP]->slice_info; slice_info_t *sli = &RC.mac[module_idP]->slice_info;
memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub)); memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub));
sli->tot_pct_dl = 0;
sli->avg_pct_dl = 1.0 / sli->n_dl;
//sli->slice_counter = sli->n_dl;
for (i = 0; i < sli->n_dl; i++) {
if (sli->dl[i].pct < 0) {
LOG_W(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid percentage %f. resetting to zero",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pct);
sli->dl[i].pct = 0;
}
sli->tot_pct_dl += sli->dl[i].pct;
}
// Check for *intra*slice share activation
if (sli->intraslice_share_active_current != sli->intraslice_share_active) {
if (sli->intraslice_share_active != 1 && sli->intraslice_share_active != 0) {
LOG_W(MAC,
"[eNB %d][DL] frame %d subframe %d: invalid intraslice sharing status (%d), revert to its previous value (%d)\n",
module_idP, frameP, subframeP, sli->intraslice_share_active, sli->intraslice_share_active_current);
sli->intraslice_share_active = sli->intraslice_share_active_current;
} else {
LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: intraslice sharing status has changed (%x-->%x)\n",
module_idP, frameP, subframeP, sli->intraslice_share_active_current, sli->intraslice_share_active);
sli->intraslice_share_active_current = sli->intraslice_share_active;
}
}
// Check for *inter*slice share activation
if (sli->interslice_share_active_current != sli->interslice_share_active) {
if (sli->interslice_share_active != 1 && sli->interslice_share_active != 0) {
LOG_W(MAC,
"[eNB %d][DL] frame %d subframe %d: invalid interslice sharing status (%d), revert to its previous value (%d)\n",
module_idP, frameP, subframeP, sli->interslice_share_active, sli->interslice_share_active_current);
sli->interslice_share_active = sli->interslice_share_active_current;
} else {
LOG_N(MAC, "[eNB %d][DL] frame %d subframe %d: interslice sharing status has changed (%x-->%x)\n",
module_idP, frameP, subframeP, sli->interslice_share_active_current, sli->interslice_share_active);
sli->interslice_share_active_current = sli->interslice_share_active;
}
}
for (i = 0; i < sli->n_dl; i++) { for (i = 0; i < sli->n_dl; i++) {
// Load any updated functions
if (sli->dl[i].update_sched > 0) {
sli->dl[i].sched_cb = dlsym(NULL, sli->dl[i].sched_name);
sli->dl[i].update_sched = 0;
sli->dl[i].update_sched_current = 0;
LOG_I(MAC, "update dl scheduler (%s) slice index %d ID %d\n",
sli->dl[i].sched_name, i, sli->dl[i].id);
}
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
if (sli->n_dl_current != sli->n_dl) {
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",
module_idP, frameP, subframeP, sli->n_dl_current, sli->n_dl);
sli->n_dl_current = sli->n_dl;
} else {
LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n",
sli->n_dl, sli->n_dl_current);
sli->n_dl = sli->n_dl_current;
}
}
// check if the slice rb share has changed, and log the console
if (sli->dl[i].pct_current != sli->dl[i].pct) { // new slice percentage
LOG_I(MAC,
"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n",
module_idP, sli->dl[i].id, frameP, subframeP,
sli->tot_pct_dl_current, sli->tot_pct_dl,
sli->dl[i].pct_current, sli->dl[i].pct);
sli->tot_pct_dl_current = sli->tot_pct_dl;
sli->dl[i].pct_current = sli->dl[i].pct;
}
// check if the slice max MCS, and log the console
if (sli->dl[i].maxmcs_current != sli->dl[i].maxmcs) {
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",
module_idP, sli->dl[i].id, frameP, subframeP,
sli->dl[i].maxmcs_current, sli->dl[i].maxmcs);
sli->dl[i].maxmcs_current = sli->dl[i].maxmcs;
} else {
LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",
module_idP, sli->dl[i].id, sli->dl[i].maxmcs, sli->dl[i].maxmcs_current);
sli->dl[i].maxmcs = sli->dl[i].maxmcs_current;
}
}
// check if a new scheduler, and log the console
if (sli->dl[i].update_sched_current != sli->dl[i].update_sched) {
LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].sched_name);
sli->dl[i].update_sched_current = sli->dl[i].update_sched;
}
} else {
// here we can correct the values, e.g. reduce proportionally
if (sli->n_dl == sli->n_dl_current) {
LOG_W(MAC,
"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
module_idP, sli->dl[i].id, sli->tot_pct_dl_current, sli->tot_pct_dl);
if (sli->dl[i].pct >= sli->avg_pct_dl) {
sli->dl[i].pct -= 0.1;
sli->tot_pct_dl -= 0.1;
}
} else {
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",
module_idP, sli->dl[i].id, sli->tot_pct_dl_current, sli->tot_pct_dl,
sli->n_dl, sli->n_dl_current);
sli->n_dl = sli->n_dl_current;
sli->dl[i].pct = sli->dl[i].pct_current;
}
}
// Check for new slice positions
if (sli->dl[i].pos_low > sli->dl[i].pos_high ||
sli->dl[i].pos_low < 0 ||
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",
module_idP, sli->dl[i].id,
sli->dl[i].pos_low, sli->dl[i].pos_high,
sli->dl[i].pos_low_current, sli->dl[i].pos_high_current);
sli->dl[i].pos_low = sli->dl[i].pos_low_current;
sli->dl[i].pos_high = sli->dl[i].pos_high_current;
} else {
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",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pos_low_current, sli->dl[i].pos_low);
sli->dl[i].pos_low_current = sli->dl[i].pos_low;
}
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",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].pos_high_current, sli->dl[i].pos_high);
sli->dl[i].pos_high_current = sli->dl[i].pos_high;
}
}
// Check for new sorting policy
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",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].sorting_current, sli->dl[i].sorting);
sli->dl[i].sorting_current = sli->dl[i].sorting;
}
// Check for new slice isolation
if (sli->dl[i].isol_current != sli->dl[i].isol) {
if (sli->dl[i].isol != 1 && sli->dl[i].isol != 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, sli->dl[i].id, frameP, subframeP, sli->dl[i].isol, sli->dl[i].isol_current);
sli->dl[i].isol = sli->dl[i].isol_current;
} else {
LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice isolation setting has changed (%x-->%x)\n",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].isol_current, sli->dl[i].isol);
sli->dl[i].isol_current = sli->dl[i].isol;
}
}
// Check for new slice priority
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 (%d-->%d)\n",
module_idP, sli->dl[i].id, frameP, subframeP, sli->dl[i].prio_current, sli->dl[i].prio);
sli->dl[i].prio_current = sli->dl[i].prio;
}
// Check for new accounting policy
if (sli->dl[i].accounting_current != sli->dl[i].accounting) {
if (sli->dl[i].accounting > 1 || sli->dl[i].accounting < 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, sli->dl[i].id, frameP, subframeP,
sli->dl[i].accounting, sli->dl[i].accounting_current);
sli->dl[i].accounting = sli->dl[i].accounting_current;
} else {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
module_idP, sli->dl[i].id, frameP, subframeP,
sli->dl[i].accounting_current, sli->dl[i].accounting);
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
sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/);
} }
......
...@@ -1038,112 +1038,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, ...@@ -1038,112 +1038,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
} }
} }
// perform slice-specifc operations
sli->tot_pct_ul = 0;
sli->avg_pct_ul = 1.0 / sli->n_ul;
for (i = 0; i < sli->n_ul; i++) { for (i = 0; i < sli->n_ul; i++) {
if (sli->ul[i].pct < 0 ){
LOG_W(MAC,
"[eNB %d][SLICE %d][UL] frame %d subframe %d: invalid percentage %f. resetting to zero",
module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].pct);
sli->ul[i].pct = 0;
}
sli->tot_pct_ul += sli->ul[i].pct;
}
for (i = 0; i < sli->n_ul; i++) {
// Load any updated functions
if (sli->ul[i].update_sched > 0 ) {
sli->ul[i].sched_cb = dlsym(NULL, sli->ul[i].sched_name);
sli->ul[i].update_sched = 0;
sli->ul[i].update_sched_current = 0;
//sli->ul[i].pct_current = sli->ul[i].pct;
//sli->tot_pct_ul_current += sli->ul[i].pct;
//if (sli->tot_pct_ul_current > 1)
//sli->tot_pct_ul_current = 1;
LOG_I(MAC,"update ul scheduler (%s) slice index %d ID %d\n",
sli->ul[i].sched_name, i, sli->ul[i].id);
}
// the new total RB share is within the range
if (sli->tot_pct_ul <= 1.0){
// check if the number of slices has changed, and log
if (sli->n_ul_current != sli->n_ul ){
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",
module_idP, frameP, subframeP, sli->n_ul_current, sli->n_ul);
sli->n_ul_current = sli->n_ul;
} else {
LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n",
sli->n_ul, sli->n_ul_current);
sli->n_ul = sli->n_ul_current;
}
}
// check if the slice rb share has changed, and log the console
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",
module_idP, sli->ul[i].id, frameP, subframeP, sli->tot_pct_ul_current,
sli->tot_pct_ul, sli->ul[i].pct_current, sli->ul[i].pct);
sli->tot_pct_ul_current = sli->tot_pct_ul;
sli->ul[i].pct_current = sli->ul[i].pct;
}
// check if the slice max MCS, and log the console
if (sli->ul[i].maxmcs_current != sli->ul[i].maxmcs){
if ((sli->ul[i].maxmcs >= 0) && (sli->ul[i].maxmcs <= 20)){
LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n",
module_idP, sli->ul[i].id, frameP, subframeP,
sli->ul[i].maxmcs_current, sli->ul[i].maxmcs);
sli->ul[i].maxmcs_current = sli->ul[i].maxmcs;
} else {
LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",
module_idP, sli->ul[i].id, sli->ul[i].maxmcs, sli->ul[i].maxmcs_current);
sli->ul[i].maxmcs = sli->ul[i].maxmcs_current;
}
}
if (sli->ul[i].first_rb_current != sli->ul[i].first_rb){
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",
module_idP, sli->ul[i].id, frameP, subframeP,
sli->ul[i].first_rb_current, sli->ul[i].first_rb);
sli->ul[i].first_rb_current = sli->ul[i].first_rb;
} else {
LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice first rb %d, revert the previous value %d\n",
module_idP, sli->ul[i].id, sli->ul[i].first_rb,
sli->ul[i].first_rb_current);
sli->ul[i].first_rb = sli->ul[i].first_rb_current;
}
}
// check if a new scheduler, and log the console
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",
module_idP, sli->ul[i].id, frameP, subframeP, sli->ul[i].sched_name);
sli->ul[i].update_sched_current = sli->ul[i].update_sched;
}
} else {
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",
module_idP, sli->ul[i].id, sli->tot_pct_ul_current, sli->tot_pct_ul);
if (sli->ul[i].pct > sli->avg_pct_ul) {
sli->ul[i].pct -= 0.1;
sli->tot_pct_ul -= 0.1;
}
} else {
// 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",
module_idP, sli->ul[i].id, sli->tot_pct_ul_current,
sli->tot_pct_ul, sli->n_ul, sli->n_ul_current);
sli->n_ul = sli->n_ul_current;
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
sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb);
} }
......
...@@ -1151,38 +1151,29 @@ typedef void (*slice_scheduler_dl)(module_id_t mod_id, ...@@ -1151,38 +1151,29 @@ typedef void (*slice_scheduler_dl)(module_id_t mod_id,
typedef struct { typedef struct {
slice_id_t id; slice_id_t id;
/// RB share for each slice for past and current time /// RB share for each slice
float pct; float pct;
float pct_current;
/// whether this slice is isolated from the others for past and current time /// whether this slice is isolated from the others
int isol; int isol;
int isol_current;
int prio; int prio;
int prio_current;
/// Frequency ranges for slice positioning /// Frequency ranges for slice positioning
int pos_low; int pos_low;
int pos_high; int pos_high;
int pos_low_current;
int pos_high_current;
// max mcs for each slice for past and current time // max mcs for each slice
int maxmcs; int maxmcs;
int maxmcs_current;
/// criteria for sorting policies of the slices /// criteria for sorting policies of the slices
uint32_t sorting; uint32_t sorting;
uint32_t sorting_current;
/// Accounting policy (just greedy(1) or fair(0) setting for now) /// Accounting policy (just greedy(1) or fair(0) setting for now)
int accounting; int accounting;
int accounting_current;
/// Whether the scheduler callback should be updated /// Whether the scheduler callback should be updated
int update_sched; int update_sched;
int update_sched_current;
/// name of available scheduler /// name of available scheduler
char *sched_name; char *sched_name;
...@@ -1202,25 +1193,20 @@ typedef void (*slice_scheduler_ul)(module_id_t mod_id, ...@@ -1202,25 +1193,20 @@ typedef void (*slice_scheduler_ul)(module_id_t mod_id,
typedef struct { typedef struct {
slice_id_t id; slice_id_t id;
/// RB share for each slice for past and current time /// RB share for each slice
float pct; float pct;
float pct_current;
// MAX MCS for each slice for past and current time // MAX MCS for each slice
int maxmcs; int maxmcs;
int maxmcs_current;
/// criteria for sorting policies of the slices /// criteria for sorting policies of the slices
uint32_t sorting; uint32_t sorting;
uint32_t sorting_current;
/// starting RB (RB offset) of UL scheduling /// starting RB (RB offset) of UL scheduling
int first_rb; int first_rb;
int first_rb_current;
/// Slice scheduler callback update needed /// Slice scheduler callback update needed
int update_sched; int update_sched;
int update_sched_current;
/// name of available scheduler /// name of available scheduler
char *sched_name; char *sched_name;
...@@ -1238,28 +1224,16 @@ typedef struct { ...@@ -1238,28 +1224,16 @@ typedef struct {
/// indicates whether remaining RBs after first intra-slice allocation will /// indicates whether remaining RBs after first intra-slice allocation will
/// be allocated to UEs of the same slice /// be allocated to UEs of the same slice
int intraslice_share_active; int intraslice_share_active;
int intraslice_share_active_current;
/// indicates whether remaining RBs after slice allocation will be /// indicates whether remaining RBs after slice allocation will be
/// allocated to UEs of another slice. Isolated slices will be ignored /// allocated to UEs of another slice. Isolated slices will be ignored
int interslice_share_active; int interslice_share_active;
int interslice_share_active_current;
/// number of active slices for past and current time in DL /// number of active DL slices
int n_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]; slice_sched_conf_dl_t dl[MAX_NUM_SLICES];
/// number of active slices for past and current time in UL /// number of active UL slices
int n_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]; slice_sched_conf_ul_t ul[MAX_NUM_SLICES];
pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
......
...@@ -138,44 +138,24 @@ void mac_top_init_eNB(void) ...@@ -138,44 +138,24 @@ void mac_top_init_eNB(void)
sli = &mac->slice_info; sli = &mac->slice_info;
sli->intraslice_share_active = 1; sli->intraslice_share_active = 1;
sli->intraslice_share_active_current = 1;
sli->interslice_share_active = 1; sli->interslice_share_active = 1;
sli->interslice_share_active_current = 1;
sli->n_dl = 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); memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES);
sli->dl[0].pct = 1.0; sli->dl[0].pct = 1.0;
sli->dl[0].pct_current = 1.0;
sli->dl[0].prio = 10; sli->dl[0].prio = 10;
sli->dl[0].prio_current = 10;
sli->dl[0].pos_high = N_RBG_MAX; 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 = 28;
sli->dl[0].maxmcs_current = 28;
sli->dl[0].sorting = 0x012345; sli->dl[0].sorting = 0x012345;
sli->dl[0].sorting_current = 0x012345;
sli->dl[0].update_sched = 1; sli->dl[0].update_sched = 1;
sli->dl[0].update_sched_current = 1;
sli->dl[0].sched_name = "schedule_ue_spec"; sli->dl[0].sched_name = "schedule_ue_spec";
sli->n_ul = 1; 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); memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES);
sli->ul[0].pct = 1.0; sli->ul[0].pct = 1.0;
sli->ul[0].pct_current = 1.0;
sli->ul[0].maxmcs = 20; sli->ul[0].maxmcs = 20;
sli->ul[0].maxmcs_current = 20;
sli->ul[0].sorting = 0x0123; sli->ul[0].sorting = 0x0123;
sli->ul[0].sorting_current = 0x0123;
sli->ul[0].update_sched = 1; sli->ul[0].update_sched = 1;
sli->ul[0].update_sched_current = 1;
sli->ul[0].sched_name = "schedule_ulsch_rnti"; sli->ul[0].sched_name = "schedule_ulsch_rnti";
} }
......
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