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
${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_f1ap.c
${NR_GNB_MAC_DIR}/slicing/nr_slicing.c
)
......
......@@ -274,7 +274,7 @@ nr_preprocessor_phytest()], multiple users in FR1
2) Checks the quantity of waiting data in RLC
3) Either set up resource allocation directly (e.g., for a single UE,
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:
* for every UE, check for retransmission and allocate as necessary
* Calculate the PF coefficient and put eligible UEs into a list
......
......@@ -723,7 +723,7 @@ int main(int argc, char **argv)
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
// 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);
N_RB_DL = gNB->frame_parms.N_RB_DL;
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
}
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;
} else {
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,
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) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
......@@ -589,13 +589,30 @@ static int comparator(const void *p, const void *q) {
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,
sub_frame_t slot,
NR_UE_info_t **UE_list,
int max_num_ue,
int n_rb_sched,
uint16_t *rballoc_mask)
uint16_t *rballoc_mask,
void *data)
{
gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
......@@ -827,6 +844,13 @@ static void pf_dl(module_id_t module_id,
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)
{
......@@ -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);
/* proportional fair scheduling algorithm */
pf_dl(module_id,
RC.nrmac[module_id]->pre_processor_dl.dl_algo.run(module_id,
frame,
slot,
UE_info->list,
max_sched_ues,
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 */
/* 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
......@@ -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,
......@@ -930,7 +960,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
return;
/* 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;
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
NR_UEs_t *UE_info = &gNB_mac->UE_info;
......
......@@ -76,7 +76,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
nfapi_nr_tx_data_request_t *TX_req);
/* \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,
frame_t frameP,
......
......@@ -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);
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;
} else {
RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(0);
......
......@@ -716,6 +716,8 @@ typedef struct {
float ul_thr_ue;
float dl_thr_ue;
long pdsch_HARQ_ACK_Codebook;
/// Assoc slice
slice_id_t dl_id;
} NR_UE_info_t;
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++)))
/**
* 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,
frame_t frame,
sub_frame_t slot);
......@@ -737,6 +752,43 @@ typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame,
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 {
f1ap_setup_req_t *setup_req;
f1ap_setup_resp_t *setup_resp;
......@@ -835,7 +887,7 @@ typedef struct gNB_MAC_INST_s {
uint32_t ulsch_max_frame_inactivity;
/// 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
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