Commit 924f28ed authored by Robert Schmidt's avatar Robert Schmidt

Refactor to call post-processor in place

Call the post-processor when the allocation is "fixed" (i.e., nothing
changes anymore), instead of having a final loop across all UEs that
might potentially be costly.

In order to calculate the PF metric, note that the statistics "reset" is
moved into pf_dl() instead of the post-processing loop, as it has to be
done on each slot.

See also: dd980302 ("Refactor to call post-processor in place")
parent 4eb43f2c
......@@ -182,13 +182,13 @@ extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */
int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1, g_pmi = 0;
void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
void nr_dlsim_preprocessor(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch)
{
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.connected_ue_list[0];
AssertFatal(RC.nrmac[module_id]->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
NR_UE_info_t *UE_info = nr_mac->UE_info.connected_ue_list[0];
AssertFatal(nr_mac->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
uint8_t nr_of_candidates = 0;
if (g_mcsIndex < 4) {
......@@ -201,8 +201,8 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
&nr_of_candidates,
sched_ctrl->search_space,4);
}
uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti);
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
uint32_t Y = get_Y(sched_ctrl->search_space, pp_pdsch->slot, UE_info->rnti);
int CCEIndex = find_pdcch_candidate(nr_mac,
/* CC_id = */ 0,
sched_ctrl->aggregation_level,
nr_of_candidates,
......@@ -210,13 +210,18 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
&sched_ctrl->sched_pdcch,
sched_ctrl->coreset,
Y);
AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti);
AssertFatal(CCEIndex >= 0,
"%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n",
pp_pdsch->frame,
pp_pdsch->slot,
0,
UE_info->rnti);
sched_ctrl->cce_index = CCEIndex;
NR_sched_pdsch_t sched_pdsch = {
.rbStart = g_rbStart,
.rbSize = g_rbSize,
.bwp_info = get_pdsch_bwp_start_size(RC.nrmac[module_id], UE_info),
.bwp_info = get_pdsch_bwp_start_size(nr_mac, UE_info),
.mcs = g_mcsIndex,
.nrOfLayers = g_nrOfLayers,
.pm_index = g_pmi,
......@@ -224,7 +229,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
/* the following might override the table that is mandated by RRC
* configuration */
current_BWP->mcsTableIdx = g_mcsTableIdx;
sched_pdsch.time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot);
sched_pdsch.time_domain_allocation = get_dl_tda(nr_mac, pp_pdsch->slot);
AssertFatal(sched_pdsch.time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n");
sched_pdsch.tda_info = get_dl_tda_info(current_BWP,
......@@ -253,7 +258,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
sched_pdsch.nrOfLayers) >> 3;
/* the simulator assumes the HARQ PID is equal to the slot number */
sched_pdsch.dl_harq_pid = slot;
sched_pdsch.dl_harq_pid = pp_pdsch->slot;
/* The scheduler uses lists to track whether a HARQ process is
* free/busy/awaiting retransmission, and updates the HARQ process states.
......@@ -262,17 +267,17 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
* Therefore, below lines just "repair" everything so that the scheduler
* won't remark that there is no HARQ feedback */
sched_ctrl->feedback_dl_harq.head = -1; // always overwrite feedback HARQ process
if (sched_ctrl->harq_processes[slot].round == 0) // depending on round set in simulation ...
add_front_nr_list(&sched_ctrl->available_dl_harq, slot); // ... make PID available
if (sched_ctrl->harq_processes[pp_pdsch->slot].round == 0) // depending on round set in simulation ...
add_front_nr_list(&sched_ctrl->available_dl_harq, pp_pdsch->slot); // ... make PID available
else
add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission
sched_ctrl->harq_processes[slot].is_waiting = false;
add_front_nr_list(&sched_ctrl->retrans_dl_harq, pp_pdsch->slot); // ... make PID retransmission
sched_ctrl->harq_processes[pp_pdsch->slot].is_waiting = false;
AssertFatal(sched_pdsch.rbStart >= 0, "invalid rbStart %d\n", sched_pdsch.rbStart);
AssertFatal(sched_pdsch.rbSize > 0, "invalid rbSize %d\n", sched_pdsch.rbSize);
AssertFatal(sched_pdsch.mcs >= 0, "invalid mcs %d\n", sched_pdsch.mcs);
AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx);
sched_ctrl->sched_pdsch = sched_pdsch;
post_process_dlsch(nr_mac, pp_pdsch, UE_info, &sched_pdsch);
}
nrUE_params_t nrUE_params;
......
......@@ -422,17 +422,17 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
return bwp_info;
}
static bool allocate_dl_retransmission(module_id_t module_id,
frame_t frame,
slot_t slot,
static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
post_process_pdsch_t *pp_pdsch,
int *n_rb_sched,
NR_UE_info_t *UE,
int beam_idx,
int current_harq_pid)
{
frame_t frame = pp_pdsch->frame;
slot_t slot = pp_pdsch->slot;
int CC_id = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
......@@ -578,7 +578,8 @@ static bool allocate_dl_retransmission(module_id_t module_id,
new_sched.rbStart = rbStart - bwp_info.bwpStart;
new_sched.pucch_allocation = alloc;
new_sched.bwp_info = bwp_info;
sched_ctrl->sched_pdsch = new_sched;
post_process_dlsch(nr_mac, pp_pdsch, UE, &new_sched);
/* retransmissions: directly allocate */
*n_rb_sched -= new_sched.rbSize;
......@@ -606,15 +607,16 @@ static int comparator(const void *p, const void *q)
return 0;
}
static void pf_dl(module_id_t module_id,
frame_t frame,
slot_t slot,
static void pf_dl(gNB_MAC_INST *mac,
post_process_pdsch_t *pp_pdsch,
NR_UE_info_t **UE_list,
int max_num_ue,
int num_beams,
int n_rb_sched[num_beams])
{
gNB_MAC_INST *mac = RC.nrmac[module_id];
frame_t frame = pp_pdsch->frame;
slot_t slot = pp_pdsch->slot;
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
// UEs that could be scheduled
UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0};
......@@ -633,15 +635,18 @@ static void pf_dl(module_id_t module_id,
if (!nr_mac_ue_is_active(UE))
continue;
const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl;
NR_mac_dir_stats_t *stats = &UE->mac_stats.dl;
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
int harq_pid = sched_ctrl->retrans_dl_harq.head;
/* Calculate Throughput */
const float a = 0.01f;
const uint32_t b = UE->mac_stats.dl.current_bytes;
const uint32_t b = stats->current_bytes;
UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b;
stats->current_bytes = 0;
stats->current_rbs = 0;
/* Check if this UE should get TA (every 100 frames). If we add the CE,
* ta_apply will be reset */
if (frame == ((sched_ctrl->ta_frame + 100) % 1024))
......@@ -659,7 +664,7 @@ static void pf_dl(module_id_t module_id,
bool sch_ret = beam.idx >= 0;
/* Allocate retransmission */
if (sch_ret)
sch_ret = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid);
sch_ret = allocate_dl_retransmission(mac, pp_pdsch, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid);
if (!sch_ret) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
......@@ -876,7 +881,7 @@ static void pf_dl(module_id_t module_id,
&sched_pdsch.tb_size,
&sched_pdsch.rbSize);
sched_ctrl->sched_pdsch = sched_pdsch;
post_process_dlsch(mac, pp_pdsch, iterator->UE, &sched_pdsch);
/* transmissions: directly allocate */
n_rb_sched[beam.idx] -= sched_pdsch.rbSize;
......@@ -889,9 +894,9 @@ static void pf_dl(module_id_t module_id,
}
}
static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
{
gNB_MAC_INST *mac = RC.nrmac[module_id];
module_id_t module_id = 0;
NR_UEs_t *UE_info = &mac->UE_info;
if (UE_info->connected_ue_list[0] == NULL)
......@@ -905,7 +910,7 @@ static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s
n_rb_sched[i] = bw;
/* Retrieve amount of data to send for this UE */
nr_store_dlsch_buffer(module_id, frame, slot);
nr_store_dlsch_buffer(module_id, pp_pdsch->frame, pp_pdsch->slot);
int average_agg_level = 4; // TODO find a better estimation
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE);
......@@ -914,7 +919,7 @@ static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s
max_sched_ues = min(max_sched_ues, MAX_DCI_CORESET);
/* proportional fair scheduling algorithm */
pf_dl(module_id, frame, slot, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched);
pf_dl(mac, pp_pdsch, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched);
}
nr_pp_impl_dl nr_init_dlsch_preprocessor(int CC_id)
......@@ -1003,7 +1008,7 @@ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *prepare_pdsch_pdu(nfapi_nr_dl_tti_request_pdu
void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch)
{
int CC_id = 0;
int module_id = 0;
int module_id = nr_mac->Mod_id;
frame_t frame = pdsch->frame;
slot_t slot = pdsch->slot;
......@@ -1371,6 +1376,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
int CC_id = 0;
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY,
"this function should be called with the scheduler mutex locked\n");
......@@ -1378,34 +1385,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
if (!is_dl_slot(slot, &gNB_mac->frame_structure))
return;
/* PREPROCESSOR */
gNB_mac->pre_processor_dl(module_id, frame, slot);
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;
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req };
const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
gNB_mac->mac_stats.total_prb_aggregate += NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE);
UE_iterator(UE_info->connected_ue_list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (!nr_mac_ue_is_active(UE) && !get_softmodem_params()->phy_test)
continue;
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
UE->mac_stats.dl.current_bytes = 0;
UE->mac_stats.dl.current_rbs = 0;
if (sched_pdsch->rbSize <= 0)
continue;
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req };
post_process_dlsch(gNB_mac, &pdsch, UE, sched_pdsch);
/* PREPROCESSOR */
gNB_mac->pre_processor_dl(gNB_mac, &pdsch);
/* mark UE as scheduled */
sched_pdsch->rbSize = 0;
}
}
......@@ -55,9 +55,11 @@ uint32_t target_dl_bw = 50;
uint64_t dlsch_slot_bitmap = (1<<1);
/* schedules whole bandwidth for first user, all the time */
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
{
gNB_MAC_INST *mac = RC.nrmac[module_id];
frame_t frame = pp_pdsch->frame;
slot_t slot = pp_pdsch->slot;
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
int slot_period = slot % mac->frame_structure.numb_slots_period;
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot_period))
......@@ -188,7 +190,7 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
target_dl_Nl)
>> 3;
sched_ctrl->sched_pdsch = sched_pdsch;
post_process_dlsch(mac, pp_pdsch, UE, &sched_pdsch);
/* mark the corresponding RBs as used */
for (int rb = 0; rb < sched_pdsch.rbSize; rb++)
......
......@@ -2974,9 +2974,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
sched_ctrl->ta_update = 31;
/* set illegal time domain allocation to force recomputation of all fields */
sched_ctrl->sched_pdsch.time_domain_allocation = -1;
/* Set default BWPs */
AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp);
......
......@@ -145,7 +145,7 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
/* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all
* freq resources */
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot);
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch);
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
* fixed set of resources */
void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
......@@ -504,5 +504,6 @@ void prepare_du_configuration_update(gNB_MAC_INST *mac,
void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group);
void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch);
void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE_info_t *UE, NR_sched_pusch_t *sched_pusch);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
......@@ -633,8 +633,6 @@ typedef struct {
/// PHR info: nominal UE transmit power levels (dBm)
int pcmax;
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pdsch_t sched_pdsch;
/// UE-estimated maximum MCS (from CSI-RS)
uint8_t dl_max_mcs;
......@@ -847,7 +845,7 @@ typedef struct {
struct gNB_MAC_INST_s;
typedef struct gNB_MAC_INST_s gNB_MAC_INST;
typedef void (*nr_pp_impl_dl)(module_id_t mod_id, frame_t frame, slot_t slot);
typedef void (*nr_pp_impl_dl)(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch);
typedef void (*nr_pp_impl_ul)(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
typedef struct f1_config_t {
......
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