Commit 2de57fbc authored by Robert Schmidt's avatar Robert Schmidt

Add Proportional Fair scheduler, wbCqi

Selects UE with highest coefficient. Allocates until there are no more
RBGs to allocate, or UE has no more data. In the latter case, continues
with the next UE (second-highest coefficient).
parent 18a6961f
develop 1 128-ues 256_QAM_demod NCTU_OpinConnect_LDPC NR-PHY-MAC-IF-multi-UE NR_10MHz NR_CSI_reporting NR_DL_sched_fixes NR_DL_scheduler NR_FAPI_beamindex_SSB_RO NR_FR2_RA NR_FR2_RRC_SSB NR_MAC_Multi_Rach_GlobalEdge NR_MAC_SSB_RO_GlobalEdge NR_MAC_SSB_RO_UE_IDCC NR_MAC_SSB_RO_merge NR_MAC_TCI_UCI_GlobalEdge NR_NGAP NR_PUCCH_MultiUE NR_RA_updates NR_RRCConfiguration_FR2 NR_RRC_config_simplified NR_SA_NGAP_RRC NR_SA_NGAP_RRC_wk42 NR_SA_itti_sim_wk48 NR_SRB_Config NR_UE_MAC_scheduler NR_UE_RA_fixes NR_UE_UL_DCI_improvements NR_UE_enable_parallelization NR_UE_stability_fixes NR_UL_scheduler NR_UL_scheduler_rebased NR_mac_uci_functions_rework NR_scheduling_CSIRS NR_scheduling_request PUSCH_TA_update RA_CI_test UE_DL_DCI_hotfix bch-fixes-bitmap benetel_5g_prach_fix benetel_phase_rotation benetel_phase_rotation_old bugfix-nr-bands bugfix-nr-ldpc-post-processing bugfix-nr-ldpc-size-typo bugfix-nr-pdcp-sn-size bugfix-nr-rate-matching-assertion cce_indexing_fix cce_indexing_fix2 ci-deploy-docker-compose ci-ul-iperf-from-trf-container cleanup_softmodem_main constant_power develop-oriecpriupdates develop-sib1 dfts_alternatives dlsch_encode_mthread dlsch_parallel dongzhanyi-zte-develop2 feature/make-s1-mme-port-configurable feature/make-s1-mme-port-configurable-with-astyle-fixes fembms-enb-ue finalize-oaicn-integration firas fix-ci-tun fix-itti-segv fix-softmodem-restart fix_do_ra_data fix_pdsch_low_prb fix_rfsim_mimo fix_rrc_x2_ticking fixes-mac-sched-nfapi fixes-mac-sched-tun fixes-tun flexran-apps flexran-repair-mme-mgmt fujitsu_lte_contribution fujitsu_lte_contribution-128 harq-hotfix hotfix-minor-remove-nr-rlc-cppcheck-error hotfix-nr-rlc-tick hotfix-ocp-executable improve_nr_modulation integration_2020_wk40 integration_2020_wk41 integration_2020_wk42_2 integration_2020_wk45 integration_2020_wk45_2 integration_2020_wk46 integration_2020_wk46_2 integration_2020_wk47 integration_2020_wk48 integration_2020_wk48_2 integration_2020_wk49 integration_2020_wk50 integration_2020_wk50_1 inter-RRU-final ldpc-decoder-codegen ldpc-decoder-codegen2 ldpc_short_codeword_fixes load_gnb lte_uplink_improvement mac-fixes-wk45_2 mosaic5g-oai-ran mosaic5g-oai-sim nfapi_nr_develop ngap-dlul ngap-support ngap-w48-merge2 ngap-wf ngap-wf-1120 ngap-wf-1120-srb ngap-wf-1120-srb-gtp ngap-wf-1120-srb-gtp-hs ngap-wf-1120-srb-gtp-hs1 ngap-wf-1120-srb-gtp-hs2 ngap-wf-1203-yunsdr ngap-wf-liuyu ngap_lfq_1120 ngap_merge noCore nr-mac-pdu-wireshark nr-mac-remove-ue-list nr-rlc-am-bugfix-w44 nr-rlc-bugfix-w44 nrUE nrUE-hs nrUE-upper-layer nr_bsr nr_dl_dmrs_type2 nr_dl_pf nr_dl_pf2 nr_dl_ul_ptrs nr_fdd_if_fix nr_prach_fr2 nr_ue_msg3 nr_ue_tti_cleanup nrue_msg2_reception nsa-ue nsa_remove_band_hardcodings oai-sim oc-docker-october-improvements openxg/develop ptrs_rrc_config pusch-mthread-scaling-fix ra-dl-ul remove_nos1_hack_pdcp remove_x2_gnb_hardcoding repair-TA revert_memcpy rh_ci_fix_autoterminate rh_ci_fr1_update rh_ci_oc rh_ci_py rh_ci_rfsim_ra rh_fr1_newjenkins rh_fr1_update rh_gnb_compile_fix rh_wk50_debug rlc-v2-bugfix-status-reporting rlc-v2-tick rrc-enb-phy-testmode s1_subnormal s1ap-bugfix-rab_setup small-bugfixes-w40 smallcleanup testing_with_external_txdata ul_dl_dci_same_slot ulsch_decode_mthread ulsim_changes x2-endc-processing yihongzheng_srb zzs
No related merge requests found
......@@ -237,6 +237,170 @@ default_sched_dl_algo_t round_robin_dl = {
};
void *pf_dl_setup(void) {
void *data = calloc(MAX_MOBILES_PER_ENB, sizeof(float));
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++)
*(float *) data = 0.0f;
AssertFatal(data, "could not allocate data in %s()\n", __func__);
return data;
}
void pf_dl_unset(void **data) {
if (*data)
free(*data);
*data = NULL;
}
int pf_wbcqi_dl_run(module_id_t Mod_id,
int CC_id,
int frame,
int subframe,
UE_list_t *UE_list,
int max_num_ue,
int n_rbg_sched,
uint8_t *rbgalloc_mask,
void *data) {
DevAssert(UE_list->head >= 0);
DevAssert(n_rbg_sched > 0);
const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id);
UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
int rbg = 0;
for (; !rbgalloc_mask[rbg]; rbg++)
; /* fast-forward to first allowed RBG */
UE_list_t UE_sched; // UEs that could be scheduled
int *uep = &UE_sched.head;
float *thr_ue = data;
float coeff_ue[MAX_MOBILES_PER_ENB];
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = UE_info->eNB_UE_stats[CC_id][UE_id].TBS;
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
// check whether there are HARQ retransmissions
const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe);
UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const uint8_t round = ue_ctrl->round[CC_id][harq_pid];
if (round != 8) { // retransmission: allocate
const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
if (nb_rb == 0)
continue;
int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize;
// needs more RBGs than we can allocate
if (nb_rbg > n_rbg_sched) {
LOG_D(MAC,
"retransmission of UE %d needs more RBGs (%d) than we have (%d)\n",
UE_id, nb_rbg, n_rbg_sched);
continue;
}
// ensure that the number of RBs can be contained by the RBGs (!), i.e.
// if we allocate the last RBG this one should have the full RBGsize
if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched
&& rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) {
LOG_D(MAC,
"retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n",
UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize);
continue;
}
const uint8_t cqi = ue_ctrl->dl_cqi[CC_id];
const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
if (idx < 0)
continue; // cannot allocate CCE
ue_ctrl->pre_dci_dl_pdu_idx = idx;
// retransmissions: directly allocate
n_rbg_sched -= nb_rbg;
ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb;
for (; nb_rbg > 0; rbg++) {
if (!rbgalloc_mask[rbg])
continue;
ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
rbgalloc_mask[rbg] = 0;
nb_rbg--;
}
LOG_D(MAC,
"%4d.%d n_rbg_sched %d after retransmission reservation for UE %d "
"round %d retx nb_rb %d pre_nb_available_rbs %d\n",
frame, subframe, n_rbg_sched, UE_id, round,
UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid],
ue_ctrl->pre_nb_available_rbs[CC_id]);
/* if there are no more RBG to give, return */
if (n_rbg_sched <= 0)
return 0;
max_num_ue--;
/* if there are no UEs that can be allocated anymore, return */
if (max_num_ue == 0)
return n_rbg_sched;
for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
} else {
if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0)
continue;
const int mcs = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
const uint32_t tbs = get_TBS_DL(mcs, RBGsize);
coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
//LOG_I(MAC, " pf UE %d: old TBS %d thr %f MCS %d TBS %d coeff %f\n",
// UE_id, b, thr_ue[UE_id], mcs, tbs, coeff_ue[UE_id]);
*uep = UE_id;
uep = &UE_sched.next[UE_id];
}
}
*uep = -1;
while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) {
int *max = &UE_sched.head; /* assume head is max */
int *p = &UE_sched.next[*max];
while (*p >= 0) {
/* if the current one has larger coeff, save for later */
if (coeff_ue[*p] > coeff_ue[*max])
max = p;
p = &UE_sched.next[*p];
}
/* remove the max one */
const int UE_id = *max;
p = &UE_sched.next[*max];
*max = UE_sched.next[*max];
*p = -1;
const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
if (idx < 0)
continue;
UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx;
max_num_ue--;
/* allocate as much as possible */
const int mcs = cqi_to_mcs[cqi];
UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs;
int req = find_nb_rb_DL(mcs,
UE_info->UE_template[CC_id][UE_id].dl_buffer_total,
n_rbg_sched * RBGsize,
RBGsize);
UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
while (req > 0 && n_rbg_sched > 0) {
ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
rbgalloc_mask[rbg] = 0;
const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize;
ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG;
req -= sRBG;
n_rbg_sched--;
for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
}
}
return n_rbg_sched;
}
default_sched_dl_algo_t proportional_fair_wbcqi_dl = {
.name = "proportional_fair_wbcqi_dl",
.setup = pf_dl_setup,
.unset = pf_dl_unset,
.run = pf_wbcqi_dl_run,
.data = NULL
};
// This function stores the downlink buffer for all the logical channels
void
store_dlsch_buffer(module_id_t Mod_id,
......
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