Commit fcaf2371 authored by Robert Schmidt's avatar Robert Schmidt

FlexRAN: Handle slice configuration

Incoming slice configuration changes are buffered in an intermediate structure.
The MAC scheduler periodically polls the agent about changes. If there has been
a slice configuration change, apply it.
parent 9d75b5c3
...@@ -52,6 +52,16 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; ...@@ -52,6 +52,16 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB];
struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB];
struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB];
/* the slice config as kept in the underlying system */
Protocol__FlexSliceConfig *slice_config[NUM_MAX_ENB];
/* a structure that keeps updates which will be reflected in slice_config later */
Protocol__FlexSliceConfig *sc_update[NUM_MAX_ENB];
/* indicates whether sc_update contains new data */
int perform_slice_config_update_count = 1;
/* queue of incoming new UE<>slice association commands */
Protocol__FlexUeConfig *ue_slice_assoc_update[NUM_MAX_UE];
int n_ue_slice_assoc_updates = 0;
int flexran_agent_mac_stats_reply(mid_t mod_id, int flexran_agent_mac_stats_reply(mid_t mod_id,
const report_config_t *report_config, const report_config_t *report_config,
...@@ -1372,8 +1382,141 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { ...@@ -1372,8 +1382,141 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
return 0; return 0;
} }
void flexran_create_config_structures(mid_t mod_id)
{
int i;
int n_dl = flexran_get_num_dl_slices(mod_id);
int m_ul = flexran_get_num_ul_slices(mod_id);
slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul);
sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul);
if (!slice_config[mod_id] || !sc_update[mod_id]) return;
for (i = 0; i < n_dl; i++) {
flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]);
}
for (i = 0; i < m_ul; i++) {
flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]);
}
}
void flexran_check_and_remove_slices(mid_t mod_id)
{
int i;
Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl;
size_t n_dl = sc_update[mod_id]->n_dl;
for (i = 0; i < n_dl; i++) {
/* remove slices whose percentage is zero */
if (dl[i]->percentage > 0) continue;
if (flexran_remove_dl_slice(mod_id, i) < 1) {
LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n",
mod_id, i, dl[i]->id);
continue;
}
LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n",
mod_id, i, dl[i]->id);
/* don't update slice_config, it will be read in below */
/* we need to memcpy the higher slice to the position we just deleted */
memcpy(dl[i], dl[n_dl-1], sizeof(*dl[n_dl-1]));
--sc_update[mod_id]->n_dl;
}
Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul;
size_t n_ul = sc_update[mod_id]->n_ul;
for (i = 0; i < n_ul; i++) {
if (ul[i]->percentage > 0) continue;
if (flexran_remove_ul_slice(mod_id, i) < 1) {
LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n",
mod_id, i, ul[i]->id);
continue;
}
LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n",
mod_id, i, ul[i]->id);
/* see DL remarks */
memcpy(ul[i], ul[n_ul-1], sizeof(*ul[n_ul-1]));
--sc_update[mod_id]->n_ul;
}
}
void flexran_agent_slice_update(mid_t mod_id)
{
int i;
int changes = 0;
if (perform_slice_config_update_count <= 0) return;
perform_slice_config_update_count--;
if (!slice_config[mod_id]) {
/* if the configuration does not exist for agent, create from eNB structure
* and exit */
flexran_create_config_structures(mod_id);
return;
}
/********* read existing config *********/
/* simply update slice_config all the time and write new config
* (apply_new_slice_dl_config() only updates if changes are necessary) */
slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id);
slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id);
for (i = 0; i < slice_config[mod_id]->n_dl; i++) {
flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
}
for (i = 0; i < slice_config[mod_id]->n_ul; i++) {
flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
}
/* in case we tried to add a slice and it failed (e.g. due to high sum
* percentage being too high), revert to the correct number of slices.
* Also, do not write if we try the last time */
if (perform_slice_config_update_count == 1) {
if (slice_config[mod_id]->n_dl != sc_update[mod_id]->n_dl) {
sc_update[mod_id]->n_dl = slice_config[mod_id]->n_dl;
LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld DL slices\n",
mod_id, sc_update[mod_id]->n_dl);
}
if (slice_config[mod_id]->n_ul != sc_update[mod_id]->n_ul) {
sc_update[mod_id]->n_ul = slice_config[mod_id]->n_ul;
LOG_W(FLEXRAN_AGENT, "[%d] reverting to original number of %ld UL slices\n",
mod_id, sc_update[mod_id]->n_ul);
}
return;
}
/********* write new config *********/
/* check for removal (sc_update[X]->dl[Y].percentage == 0)
* and update sc_update & slice_config accordingly */
flexran_check_and_remove_slices(mod_id);
/* create new DL and UL slices if necessary */
for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) {
flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id, 0);
slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id);
flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
}
for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) {
flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id, 0);
slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id);
flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
}
for (i = 0; i < slice_config[mod_id]->n_dl; i++) {
changes += apply_new_slice_dl_config(mod_id,
slice_config[mod_id]->dl[i],
sc_update[mod_id]->dl[i]);
}
for (i = 0; i < slice_config[mod_id]->n_ul; i++) {
changes += apply_new_slice_ul_config(mod_id,
slice_config[mod_id]->ul[i],
sc_update[mod_id]->ul[i]);
}
if (n_ue_slice_assoc_updates > 0) {
changes += apply_ue_slice_assoc_update(mod_id);
}
if (changes > 0)
LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes);
}
Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id)
{
return slice_config[mod_id];
}
...@@ -87,4 +87,14 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface); ...@@ -87,4 +87,14 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface);
/*Unregister technology specific callbacks*/ /*Unregister technology specific callbacks*/
int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface*xface); int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface*xface);
/***************************************
* FlexRAN agent - slice configuration *
***************************************/
/* Inform controller about possibility to update slice configuration */
void flexran_agent_slice_update(mid_t mod_id);
/* return a pointer to the current config */
Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id);
#endif #endif
...@@ -107,4 +107,37 @@ int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); ...@@ -107,4 +107,37 @@ int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser);
int load_dl_scheduler_function(mid_t mod_id, const char *function_name); int load_dl_scheduler_function(mid_t mod_id, const char *function_name);
/*** Functions for handling a slice config ***/
/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice
* configs and m_ul UL slice configs */
Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul);
/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice
* struct */
void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice);
/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice
* struct */
void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice);
/* reads content of slice over the sc_update structure, so that it can be
* applied later by performing a diff between slice_config and sc_update */
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice);
/* apply new configuration of slice in DL if there are changes between the
* parameters. Returns the number of changed parameters. */
int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc);
/* apply new configuration of slice in UL if there are changes between the
* parameters. Returns the number of changed parameters. */
int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc);
/* inserts a new ue_config into the structure keeping ue to slice association
* updates and marks so it can be applied */
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config);
/* apply a new association between a UE and a slice (both DL and UL) */
int apply_ue_slice_assoc_update(mid_t mod_id);
#endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/
...@@ -703,6 +703,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, ...@@ -703,6 +703,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2);
} }
if (mac_agent_registered[module_idP] && subframeP == 9) {
flexran_agent_slice_update(module_idP);
}
stop_meas(&RC.mac[module_idP]->eNB_scheduler); stop_meas(&RC.mac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
......
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