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
Branches unavailable
2025.w14 2025.w13 2025.w12 2025.w11 2025.w10 2025.w09 2025.w08 2025.w07 2025.w06 2025.w05 2025.w04 2025.w03 2025.w02 2024.w51 2024.w50 2024.w49 2024.w48 2024.w47 2024.w46 2024.w45 2024.w44 2024.w43 2024.w42 2024.w41 2024.w40 2024.w39 2024.w38 2024.w36 2024.w35 2024.w34 2024.w33 2024.w32 2024.w31 2024.w30 2024.w29 2024.w28 2024.w27 2024.w26 2024.w25 2024.w24 2024.w23 2024.w22 2024.w21 2024.w18 2024.w17 2024.w16 2024.w15 2024.w14 2024.w13 2024.w12 2024.w11 2024.w10 2024.w09 2024.w08 2024.w06 2024.w05 2024.w04 2024.w03 2024.w02 2024.w01 2023.w51 2023.w50 2023.w49 2023.w48 2023.w47 2023.w45 2023.w43 2023.w42 2023.w41 2023.w40 2023.w39 2023.w38 2023.w37 2023.w36 2023.w34 2023.w33 2023.w32 2023.w31 2023.w30 2023.w29 2023.w28 2023.w27 2023.w26 2023.w25 2023.w24 2023.w23 2023.w22 2023.w21 2023.w20 2023.w19 2023.w18 2023.w18b 2023.w16 2023.w15 2023.w14 2023.w13 2023.w12 2023.w11 2023.w11b 2023.w10 2023.w10b 2023.w09 2023.w08 2023.w08b 2023.w07 2023.w06 2023.w05 2023.w03 2023.w02 2022.42 2022.41 2022.w51 2022.w50 2022.w49 2022.w48 2022.w47 2022.w46 2022.w45 2022.w43 2022.w42 2022.w42b 2022.w41 2022.w40 2022.w39 2022.w38 2022.w37 2022.w37b 2022.w36 2022.w35 2022.w33 2022.w32 2022.w31 2022.w31b 2022.w30 2022.w29 2022.w26 2022.w25 2022.w24 2022.w24b 2022.w23 2022.w22 2022.w21 2022.w20 2022.w19 2022.w18 2022.w17 2022.w15 2022.w15b 2022.w14a 2022.w13 2022.w13b 2022.w13a 2022.w12 2022.w10 2022.w09 2022.w09b 2022.w08 2022.w08b 2022.w07 2022.w07b 2022.w06 2022.w06a 2022.w05 2022.w05b 2022.w03_hotfix 2022.w03_b 2022.w02 2022.w01 2021.wk46 2021.wk14_a 2021.wk13_d 2021.wk13_c 2021.w51_c 2021.w51_a 2021.w50_a 2021.w49_b 2021.w49_a 2021.w48 2021.w47 2021.w46 2021.w46-powder 2021.w45 2021.w45_b 2021.w44 2021.w43 2021.w42 2021.w37 2021.w36 2021.w35 2021.w34 2021.w33 2021.w32 2021.w31 2021.w30 2021.w29 2021.w28 2021.w27 2021.w26 2021.w25 2021.w24 2021.w23 2021.w22 2021.w20 2021.w19 2021.w18_b 2021.w18_a 2021.w17_b 2021.w16 2021.w15 2021.w14 2021.w13_a 2021.w12 2021.w11 2021.w10 2021.w09 2021.w08 2021.w06 2021.w05 2021.w04 2021.w02 2020.w51_2 2020.w51 2020.w50 2020.w49 2020.w48_2 2020.w48 2020.w47 2020.w46_2 2020.w46 2020.w45_2 2020.w45 2020.w44 2020.w42_2 2020.w42 2020.w41 2020.w39 2020.w38 2020.w37 2020.w36 2020.w34 2020.w33 2020.w31 2020.w30 2020.w29 2020.w28 2020.w26 2020.w25 2020.w24 2020.w23 2020.w22 2020.w19 2020.w17 2020.w16 2020.w15 2020.w11 2020.w09 2020.w06 2020.w05 2020.w04 2020.w03 2019.w51 2019.w44 2019.w41 2019.w36 2019.w30 2019.w28 2019.w27 2019.w25 2019.w23 2019.w21 2019.w17 2019.w15 2019.w13 2019.w11 2019.w10 2019.w09 2019.w08 2019.w07 2019.w06 2019.w04 2019.w03 2018.w51 2018.w48 2018.w47 2018.w46 2018.w44 2018.w41 2018.w40 2018.w39 2018.w36 v2.2.0 v2.1.0 v2.0.0 v1.2.2 v1.2.1 v1.2.0 v1.1.1 v1.1.0 v1.0.3 v1.0.2 v1.0.1 v1.0.0 setparam osa-etsi-ws-ue osa-etsi-ws-try2 osa-etsi-ws-try1 osa-etsi-ws-gNB nr-ip-over-lte nr-ip-over-lte-v.1.5 nr-ip-over-lte-v.1.4 nr-ip-over-lte-v.1.3 nr-ip-over-lte-v.1.2 nr-ip-over-lte-v.1.1 nr-ip-over-lte-v.1.0 flexran-eol develop-nr-pdcch develop-nr-2020w03 develop-nr-2020w02 develop-nr-2019w51 develop-nr-2019w50 develop-nr-2019w48 develop-nr-2019w47 develop-nr-2019w45 develop-nr-2019w43 develop-nr-2019w42 develop-nr-2019w40 develop-nr-2019w28 develop-nr-2019w23 benetel_phase_rotation benetel_gnb_rel_2.0 benetel_gnb_rel_1.0 benetel_enb_rel_2.0 benetel_enb_rel_1.0 ARC_1.3
No related merge requests found
...@@ -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