Commit e2223d71 authored by Robert Schmidt's avatar Robert Schmidt Committed by Chieh-Chun Chen

Add 5G preprocessor with NVS slicing

parent 3f3a9869
...@@ -1366,6 +1366,7 @@ set (MAC_NR_SRC ...@@ -1366,6 +1366,7 @@ set (MAC_NR_SRC
${NR_GNB_MAC_DIR}/mac_rrc_dl_handler.c ${NR_GNB_MAC_DIR}/mac_rrc_dl_handler.c
${NR_GNB_MAC_DIR}/mac_rrc_ul_direct.c ${NR_GNB_MAC_DIR}/mac_rrc_ul_direct.c
${NR_GNB_MAC_DIR}/mac_rrc_ul_f1ap.c ${NR_GNB_MAC_DIR}/mac_rrc_ul_f1ap.c
${NR_GNB_MAC_DIR}/slicing/nr_slicing.c
) )
......
...@@ -274,7 +274,7 @@ nr_preprocessor_phytest()], multiple users in FR1 ...@@ -274,7 +274,7 @@ nr_preprocessor_phytest()], multiple users in FR1
2) Checks the quantity of waiting data in RLC 2) Checks the quantity of waiting data in RLC
3) Either set up resource allocation directly (e.g., for a single UE, 3) Either set up resource allocation directly (e.g., for a single UE,
phytest), or call into a function to perform actual resource allocation. phytest), or call into a function to perform actual resource allocation.
Currently, this is done using pf_dl() which implements a basic Currently, this is done using nr_pf_dl() which implements a basic
proportional fair scheduler: proportional fair scheduler:
* for every UE, check for retransmission and allocate as necessary * for every UE, check for retransmission and allocate as necessary
* Calculate the PF coefficient and put eligible UEs into a list * Calculate the PF coefficient and put eligible UEs into a list
......
...@@ -723,7 +723,7 @@ int main(int argc, char **argv) ...@@ -723,7 +723,7 @@ int main(int argc, char **argv)
nr_mac_add_test_ue(RC.nrmac[0], secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, secondaryCellGroup); nr_mac_add_test_ue(RC.nrmac[0], secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, secondaryCellGroup);
// reset preprocessor to the one of DLSIM after it has been set during // reset preprocessor to the one of DLSIM after it has been set during
// nr_mac_config_scc() // nr_mac_config_scc()
gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; gNB_mac->pre_processor_dl.dl = nr_dlsim_preprocessor;
phy_init_nr_gNB(gNB); phy_init_nr_gNB(gNB);
N_RB_DL = gNB->frame_parms.N_RB_DL; N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0]; NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0];
......
...@@ -818,7 +818,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c ...@@ -818,7 +818,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
} }
if (get_softmodem_params()->phy_test) { if (get_softmodem_params()->phy_test) {
nrmac->pre_processor_dl = nr_preprocessor_phytest; nrmac->pre_processor_dl.dl = nr_preprocessor_phytest;
nrmac->pre_processor_ul = nr_ul_preprocessor_phytest; nrmac->pre_processor_ul = nr_ul_preprocessor_phytest;
} else { } else {
nrmac->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(0); nrmac->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(0);
......
...@@ -317,7 +317,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, ...@@ -317,7 +317,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
return offset; return offset;
} }
static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slot) void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slot)
{ {
UE_iterator(RC.nrmac[module_id]->UE_info.list, UE) { UE_iterator(RC.nrmac[module_id]->UE_info.list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
...@@ -589,13 +589,30 @@ static int comparator(const void *p, const void *q) { ...@@ -589,13 +589,30 @@ static int comparator(const void *p, const void *q) {
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef; return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
} }
static void pf_dl(module_id_t module_id, static void *nr_pf_dl_setup(void)
{
void *data = malloc(MAX_MOBILES_PER_GNB * sizeof(float));
AssertFatal(data, "%s(): could not allocate data\n", __func__);
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++)
*(float *) data = 0.0f;
return data;
}
static void nr_pf_dl_unset(void **data)
{
DevAssert(data);
if (*data)
free(*data);
*data = NULL;
}
static void nr_pf_dl(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot, sub_frame_t slot,
NR_UE_info_t **UE_list, NR_UE_info_t **UE_list,
int max_num_ue, int max_num_ue,
int n_rb_sched, int n_rb_sched,
uint16_t *rballoc_mask) uint16_t *rballoc_mask,
void *data)
{ {
gNB_MAC_INST *mac = RC.nrmac[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
...@@ -827,6 +844,13 @@ static void pf_dl(module_id_t module_id, ...@@ -827,6 +844,13 @@ static void pf_dl(module_id_t module_id,
iterator++; iterator++;
} }
} }
nr_dl_sched_algo_t nr_proportional_fair_wbcqi_dl = {
.name = "nr_proportional_fair_wbcqi_dl",
.setup = nr_pf_dl_setup,
.unset = nr_pf_dl_unset,
.run = nr_pf_dl,
.data = NULL
};
static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
{ {
...@@ -878,16 +902,17 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_ ...@@ -878,16 +902,17 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE);
/* proportional fair scheduling algorithm */ /* proportional fair scheduling algorithm */
pf_dl(module_id, RC.nrmac[module_id]->pre_processor_dl.dl_algo.run(module_id,
frame, frame,
slot, slot,
UE_info->list, UE_info->list,
max_sched_ues, max_sched_ues,
n_rb_sched, n_rb_sched,
rballoc_mask); rballoc_mask,
RC.nrmac[module_id]->pre_processor_dl.dl_algo.data);
} }
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { nr_pp_impl_param_dl_t nr_init_fr1_dlsch_preprocessor(int CC_id) {
/* during initialization: no mutex needed */ /* during initialization: no mutex needed */
/* in the PF algorithm, we have to use the TBsize to compute the coefficient. /* in the PF algorithm, we have to use the TBsize to compute the coefficient.
* This would include the number of DMRS symbols, which in turn depends on * This would include the number of DMRS symbols, which in turn depends on
...@@ -912,7 +937,12 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { ...@@ -912,7 +937,12 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) {
} }
} }
return nr_fr1_dlsch_preprocessor; nr_pp_impl_param_dl_t impl;
memset(&impl, 0, sizeof(impl));
impl.dl = nr_fr1_dlsch_preprocessor;
impl.dl_algo = nr_proportional_fair_wbcqi_dl;
impl.dl_algo.data = impl.dl_algo.setup();
return impl;
} }
void nr_schedule_ue_spec(module_id_t module_id, void nr_schedule_ue_spec(module_id_t module_id,
...@@ -930,7 +960,10 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -930,7 +960,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
return; return;
/* PREPROCESSOR */ /* PREPROCESSOR */
gNB_mac->pre_processor_dl(module_id, frame, slot); pthread_mutex_lock(&gNB_mac->UE_info.mutex);
gNB_mac->pre_processor_dl.dl(module_id, frame, slot);
pthread_mutex_unlock(&gNB_mac->UE_info.mutex);
const int CC_id = 0; const int CC_id = 0;
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
NR_UEs_t *UE_info = &gNB_mac->UE_info; NR_UEs_t *UE_info = &gNB_mac->UE_info;
......
...@@ -76,7 +76,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -76,7 +76,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
nfapi_nr_tx_data_request_t *TX_req); nfapi_nr_tx_data_request_t *TX_req);
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ /* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id); nr_pp_impl_param_dl_t nr_init_fr1_dlsch_preprocessor(int CC_id);
void schedule_nr_sib1(module_id_t module_idP, void schedule_nr_sib1(module_id_t module_idP,
frame_t frameP, frame_t frameP,
......
...@@ -259,7 +259,7 @@ void mac_top_init_gNB(ngran_node_t node_type, ...@@ -259,7 +259,7 @@ void mac_top_init_gNB(ngran_node_t node_type,
uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator); uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator);
if (get_softmodem_params()->phy_test) { if (get_softmodem_params()->phy_test) {
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; RC.nrmac[i]->pre_processor_dl.dl = nr_preprocessor_phytest;
RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest; RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
} else { } else {
RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(0); RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(0);
......
...@@ -716,6 +716,8 @@ typedef struct { ...@@ -716,6 +716,8 @@ typedef struct {
float ul_thr_ue; float ul_thr_ue;
float dl_thr_ue; float dl_thr_ue;
long pdsch_HARQ_ACK_Codebook; long pdsch_HARQ_ACK_Codebook;
/// Assoc slice
slice_id_t dl_id;
} NR_UE_info_t; } NR_UE_info_t;
typedef struct { typedef struct {
...@@ -730,6 +732,19 @@ typedef struct { ...@@ -730,6 +732,19 @@ typedef struct {
#define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++))) #define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++)))
/**
* definition of a scheduling algorithm implementation used in the
* default DL scheduler
*/
typedef struct {
char *name;
void *(*setup)(void);
void (*unset)(void **);
void (*run)(
module_id_t, frame_t, sub_frame_t, NR_UE_info_t **, int, int, uint16_t *, void *);
void *data;
} nr_dl_sched_algo_t;
typedef void (*nr_pp_impl_dl)(module_id_t mod_id, typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
frame_t frame, frame_t frame,
sub_frame_t slot); sub_frame_t slot);
...@@ -737,6 +752,43 @@ typedef bool (*nr_pp_impl_ul)(module_id_t mod_id, ...@@ -737,6 +752,43 @@ typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame, frame_t frame,
sub_frame_t slot); sub_frame_t slot);
struct nr_slice_info_s;
struct nr_slice_s;
typedef struct {
int algorithm;
/// inform the slice algorithm about a new UE
void (*add_UE)(struct nr_slice_info_s *s, NR_UE_info_t **UE_list);
/// inform the slice algorithm about a UE that disconnected
void (*remove_UE)(struct nr_slice_info_s *s, NR_UE_info_t* rm_ue, int idx);
/// move a UE to a slice in DL/UL, -1 means don't move (no-op).
void (*move_UE)(struct nr_slice_info_s *s, NR_UE_info_t* assoc_ue, int old_idx, int new_idx);
/// get UE associated slice's index
int (*get_UE_slice_idx)(struct nr_slice_info_s *s, uint16_t rnti);
/// get UE's index from the slice
int (*get_UE_idx)(struct nr_slice_s *si, uint16_t rnti);
/// Adds a new slice through admission control. slice_params are
/// algorithm-specific parameters. sched is either a default_sched_ul_algo_t
/// or default_sched_dl_algo_t, depending on whether this implementation
/// handles UL/DL. If slice at index exists, updates existing
/// slice. Returns index of new slice or -1 on failure.
int (*addmod_slice)(struct nr_slice_info_s *s,
int id,
char *label,
void *sched,
void *slice_params);
/// Returns slice through slice_idx. 1 if successful, 0 if not.
int (*remove_slice)(struct nr_slice_info_s *s, uint8_t slice_idx);
nr_pp_impl_dl dl;
nr_dl_sched_algo_t dl_algo;
void (*destroy)(struct nr_slice_info_s **s);
struct nr_slice_info_s *slices;
} nr_pp_impl_param_dl_t;
typedef struct f1_config_t { typedef struct f1_config_t {
f1ap_setup_req_t *setup_req; f1ap_setup_req_t *setup_req;
f1ap_setup_resp_t *setup_resp; f1ap_setup_resp_t *setup_resp;
...@@ -835,7 +887,7 @@ typedef struct gNB_MAC_INST_s { ...@@ -835,7 +887,7 @@ typedef struct gNB_MAC_INST_s {
uint32_t ulsch_max_frame_inactivity; uint32_t ulsch_max_frame_inactivity;
/// DL preprocessor for differentiated scheduling /// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl; nr_pp_impl_param_dl_t pre_processor_dl;
/// UL preprocessor for differentiated scheduling /// UL preprocessor for differentiated scheduling
nr_pp_impl_ul pre_processor_ul; nr_pp_impl_ul pre_processor_ul;
......
This diff is collapsed.
/*
* 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 nr_slicing.h
* \brief General NR slice definition and helper parameters
* \author Robert Schmidt
* \date 2021
* \email robert.schmidt@eurecom.fr
*/
#ifndef NR_SLICING_H__
#define NR_SLICING_H__
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
typedef struct nr_slice_s {
/// Arbitrary ID
slice_id_t id;
/// Arbitrary label
char *label;
nr_dl_sched_algo_t dl_algo;
/// A specific algorithm's implementation parameters
void *algo_data;
/// Internal data that might be kept alongside a slice's params
void *int_data;
// list of users in this slice
NR_list_t UEs;
NR_UE_info_t *UE_list[MAX_MOBILES_PER_GNB+1];
} nr_slice_t;
typedef struct nr_slice_info_s {
uint8_t num;
nr_slice_t **s;
uint8_t UE_assoc_slice[MAX_MOBILES_PER_GNB+1];
} nr_slice_info_t;
#define NVS_SLICING 20
/* arbitrary upper limit, increase if you want to instantiate more slices */
#define MAX_NVS_SLICES 10
/* window for slice weight averaging -> 1s for fine granularity */
#define BETA 0.001f
typedef struct {
enum nvs_type {NVS_RATE, NVS_RES} type;
union {
struct { float Mbps_reserved; float Mbps_reference; };
struct { float pct_reserved; };
};
} nvs_nr_slice_param_t;
nr_pp_impl_param_dl_t nvs_nr_dl_init(module_id_t mod_id, int CC_id);
#endif /* NR_SLICING_H__ */
/*
* 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 nr_slicing_internal.h
* \brief Internal NR slice helper functions
* \author Robert Schmidt
* \date 2021
* \email robert.schmidt@eurecom.fr
*/
#ifndef NR_SLICING_INTERNAL_H__
#define NR_SLICING_INTERNAL_H__
#include "nr_slicing.h"
void nr_slicing_add_UE(nr_slice_info_t *si, NR_UE_info_t **UE_list);
void nr_slicing_remove_UE(nr_slice_info_t *si, NR_UE_info_t* rm_ue, int idx);
void nr_slicing_move_UE(nr_slice_info_t *si, NR_UE_info_t* assoc_ue, int old_idx, int new_idx);
int nr_slicing_get_UE_slice_idx(nr_slice_info_t *si, uint16_t rnti);
int nr_slicing_get_UE_idx(nr_slice_t *si, uint16_t rnti);
nr_slice_t *_nr_add_slice(uint8_t *n, nr_slice_t **s);
nr_slice_t *_nr_remove_slice(uint8_t *n, nr_slice_t **s, int idx);
#endif /* NR_SLICING_INTERNAL_H__ */
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